JTIM JTIM - 2 months ago 28
ASP.NET (C#) Question

Azure Custom Controller / API .Net backend

I have had a MobileService running on Azure, and have decided to create a new service and migrate the code myself. The new service is of the new type called: Azure Mobile App Service.

Currently I have Authentication working, and can do migrations/update-database. I am following the TodoItem example. I now want to create my own Custom API, which easily worked on MobileService, but I cannot get it working on Azure Mobile App :/

I have followed these two links web-Api-routing and app-service-mobile-backend. And I now have the following:

I have created a new controller:

[MobileAppController]
public class TestController : ApiController
{
// GET api/Test
[Route("api/Test/completeAll")]
[HttpPost]
public async Task<ihttpactionresult> completeAll(string info)
{
return Ok(info + info + info);
}
}


In the mobileApp.cs I have added the below code according to backend:

HttpConfiguration config = new HttpConfiguration();
config.MapHttpAttributeRoutes();


Additionally I have installed the below package according to web-api-routing:

Microsoft.AspNet.WebApi.WebHost


and the call from the client:

string t = await App.MobileService.InvokeApiAsync<string,string>("Test/completeAll", "hej");


Debug shows, that it is the correct URL:


{Method: POST, RequestUri: 'https://xxxxxxx.azurewebsites.net/api/Test/completeAll',
Version: 1.1, Content: System.Net.Http.StringContent, Headers:{ X-ZUMO-FEATURES:
AT X-ZUMO-INSTALLATION-ID: e9b359df-d15e-4119-a4ad-afe3031d8cd5 X-ZUMO-AUTH:
xxxxxxxxxxx Accept: application/json User-Agent:
ZUMO/2.0 User-Agent: (lang=Managed; os=Windows Store; os_version=--; arch=Neutral; version=2.0.31125.0)
X-ZUMO-VERSION: ZUMO/2.0 (lang=Managed; os=Windows Store; os_version=--; arch=Neutral; version=2.0.31125.0)
ZUMO-API-VERSION: 2.0.0 Content-Type: application/json; charset=utf-8 Content-Length: 3}}


But keep getting: 404 (Not Found)
Debug Message "The request could not be completed. (Not Found)"

What am I missing :/ ?

Update

I have tried expanding the code in The mobileApp.cs, with:

HttpConfiguration config = new HttpConfiguration();
new MobileAppConfiguration()
.UseDefaultConfiguration().MapApiControllers()
.ApplyTo(config);
config.MapHttpAttributeRoutes();
app.UseWebApi(config);


based on app-service-backend, however still no access :/

Update



I used fiddler2 to access the endpoint through a browser and got the following results:

Fiddler output

Update Again

I have tried to create another minimal solution, but still get the same error. Are there any great tutorials that I can follow to achieve this functionality?

The positive feeling is slowly evaporating . . .

The question is also running now on msdn, I will update here if any information is shown there.




Update



Tested Lindas comment, and I can in fact access the value converter:

// Use the MobileAppController attribute for each ApiController you want to use
// from your mobile clients
[MobileAppController]
public class ValuesController : ApiController
{
// GET api/values
public string Get()
{
MobileAppSettingsDictionary settings = this.Configuration.GetMobileAppSettingsProvider().GetMobileAppSettings();
ITraceWriter traceWriter = this.Configuration.Services.GetTraceWriter();

string host = settings.HostName ?? "localhost";
string greeting = "Hello from " + host;

traceWriter.Info(greeting);
return greeting;
}

// POST api/values
public string Post()
{
return "Hello World!";
}

}


This I access using the both the post and get function:

string t = await App.MobileService.InvokeApiAsync<string, string>("values", null, HttpMethod.Post, null);


or

string t = await App.MobileService.InvokeApiAsync<string, string>("values", null, HttpMethod.Get, null);


But the code I pasted has no route so why can I access it using values? What would the path be to the original controller if did not use the route parameter?




Extra Information

I have now created a support ticket with Microsoft and will update with additional information. . . Hopefully.

Update
Info from MSDN Forum: try MS_SkipVersionCheck
Reading about the attribute here, it does not seem applicable. But I tried it. Still
Not Found
for my API but the original one is still working. So it did not have an impact on this issue.

Answer

Yes !!!

So I finally got it working, I copied the usings from lidydonna - msft git and read about .net backend for mobileservice.

This ended with the following:

using System.Web.Http;
using Microsoft.Azure.Mobile.Server.Config;
using System.Threading.Tasks;
using System.Web.Http.Tracing;
using Microsoft.Azure.Mobile.Server;

namespace BCMobileAppService.Controllers
{
[MobileAppController]
public class TestController : ApiController
{
    // GET api/Test
    [HttpGet, Route("api/Test/completeAll")]
    public string Get()
    {
        MobileAppSettingsDictionary settings = this.Configuration.GetMobileAppSettingsProvider().GetMobileAppSettings();
        ITraceWriter traceWriter = this.Configuration.Services.GetTraceWriter();

            string host = settings.HostName ?? "localhost";
            string greeting = "Hello from " + host;

            traceWriter.Info(greeting);
            return greeting;
        }

        // POST api/values
        [HttpPost, Route("api/Test/completeAll")]
        public string Post(string hej)
        {
            string retVal = "Hello World!" + hej;
            return retVal;
        }
    }
}

This is a new controller and not the one that comes with it as lidydonna used. It seemed like it wants both functions get and post. This resulted in the API was registered and could be accessed. This means the client call to the server I used was:

t = await App.MobileService.InvokeApiAsync<string, string>("Test/completeAll", null, HttpMethod.Post, new Dictionary<string, string>() { { "hej", " AWESOME !" }});

dialog = new MessageDialog(t);
dialog.Commands.Add(new UICommand("OK"));
await dialog.ShowAsync();

AND I GOT A RESPONSE YAY!!

Extra Information

The controllers that you create, i.e. the class needs to end with Controller, you can have text before but not after. This information was given on a MSDN forum discussion.

If the post and the get has the same input the server returns Not found. Having different inputs solves the issue.