locked
Azure Mobile Apps Custom API .Net backend - Second Controller RRS feed

  • Question

  • Profanities ! (blowing off some steam, now to the question.)

    A month ago I had these questions running:

    msdn - Azure Mobile Apps Custom API .Net backend

    stackoverflow - Azure Mobile Apps Custom API .Net backend

    Happy with myself that I solved the issue. I then did not have time to look at this, beacuse of more pressing matters on the client side.
    Now the server is again in focus. I now need to create a new controller and a new route. Copy-paste from the answer in stackoverflow, and done...

    Ohhhhh NO! (NOT again) I simply do not get why it is so much harder to get this working than on the old MobileService.

    What do you have to do to get controllers registered ? :/

    I have tried publishing the controller individually from the project instead of only during it through the publishing of the entire app-service, with no success.

    EXTRA

    The current Starup class:

    public partial class Startup
    {
        public static void ConfigureMobileApp(IAppBuilder app)
        {
            HttpConfiguration config = new HttpConfiguration();
    
            //For more information on Web API tracing, see http://go.microsoft.com/fwlink/?LinkId=620686 
            config.EnableSystemDiagnosticsTracing();
            config.MapHttpAttributeRoutes();
    
            new MobileAppConfiguration()
                .UseDefaultConfiguration()
                .ApplyTo(config);
            // Also tried with .MapApiController
    
            // Use Entity Framework Code First to create database tables based on your DbContext
            Database.SetInitializer(new BCMobileAppInitializer());
    
            // To prevent Entity Framework from modifying your database schema, use a null database initializer
            // Database.SetInitializer<BCMobileAppContext>(null);
    
            MobileAppSettingsDictionary settings = config.GetMobileAppSettingsProvider().GetMobileAppSettings();
    
            if (string.IsNullOrEmpty(settings.HostName))
            {
                // This middleware is intended to be used locally for debugging. By default, HostName will
                // only have a value when running in an App Service application.
                app.UseAppServiceAuthentication(new AppServiceAuthenticationOptions
                {
                    SigningKey = ConfigurationManager.AppSettings["SigningKey"],
                    ValidAudiences = new[] { ConfigurationManager.AppSettings["ValidAudience"] },
                    ValidIssuers = new[] { ConfigurationManager.AppSettings["ValidIssuer"] },
                    TokenHandler = config.GetAppServiceTokenHandler()
                });
            }
            app.UseWebApi(config);
        }
    }

    The new controller:

    using System.Web.Http;
    using Microsoft.Azure.Mobile.Server.Config;
    using System.Threading.Tasks;
    using System.Web.Http.Tracing;
    using Microsoft.Azure.Mobile.Server;
    using BCMobileAppService.Models;
    using System.Linq;
    using DTO;
    using System;
    
    namespace BCMobileAppService.Controllers
    {
    [MobileAppController]
    public class TestController2 : ApiController
    {
        // Post api/Test
        [HttpPost, Route("api/user/create")]
        public IHttpActionResult Post(UsernameCheckDto dto)
        {
            var telemetry = new Microsoft.ApplicationInsights.TelemetryClient();
            telemetry.TrackTrace("UsernameCheck", Microsoft.ApplicationInsights.DataContracts.SeverityLevel.Information);
            using (BCMobileAppContext db = new BCMobileAppContext())
            {
    
                telemetry.TrackTrace("UsernameCheck 2");
                string Username_NoSpaces = dto.Username.Replace(" ", "");
                telemetry.TrackTrace("UsernameCheck 3");
                var user = db.Users.FirstOrDefault(u => u.Username_NoSpaces == Username_NoSpaces);
                telemetry.TrackTrace("UsernameCheck 4");
    
                if (user == null && !Username_NoSpaces.Contains(","))
                {
                    telemetry.TrackTrace("UsernameCheck Done 1");
                    return Ok(true);
                }
                telemetry.TrackTrace("UsernameCheck Done 2");
                return Ok(false);
    
    
            }
        }
    
        // Get api/values
        [HttpGet, Route("api/user/create")]
        public IHttpActionResult Get(string hej)
        {
            string retVal = "Hello World! " + hej;
            return Ok(retVal);
        }
    }
    }


    • Edited by JOTM123 Wednesday, April 6, 2016 1:12 PM
    Wednesday, April 6, 2016 7:27 AM

Answers

All replies

  • Hello,

    Thank you for posting here!

    404 error seems because of, if the request URI did not match a route for the mobile API application.

    You can try following:

    Add a default value specifying the TestController2 controller to the first rout.

    For more details, kindly refer the below link:

    https://blogs.msdn.microsoft.com/webdev/2013/04/04/debugging-asp-net-web-api-with-route-debugger/

    Hope it helps.

    Regards,

    Swikruti

    Wednesday, April 6, 2016 4:13 PM
  • Hello Swikruti,

    I agree that the route must be wrong, but as the picture shows and the code should be the same?

    Trying the link you suggested gave me this:

    Trying the helper from this link did not help either.

    Other suggestions?

    **Update**

    I have enabled swagger but no API's are showing, even those who work. How do I enable swagger to find all API's?

    • Edited by JOTM123 Wednesday, April 6, 2016 7:31 PM
    Wednesday, April 6, 2016 7:08 PM
  • Hi,

    I think the main problem is that your class name is TestController2.

    Change it to Test2Controller, and that should solve the problem.

    WebApi expects Controller class names to follow a certain convention.  TestController2 doesn't get discovered as a controller during route mapping because it doesn't end with "Controller".


    Here's a blog post describing why this is: http://www.strathweb.com/2013/02/but-i-dont-want-to-call-web-api-controllers-controller/

    Wednesday, April 6, 2016 7:52 PM
  • Okay I will try this tomorrow THX!

    Also could it make sense to map the routes instead manually? If so how would I do this?

    Furthermore I have changed the question to try and map the routes instead of relying on MapApiControllers. The mapping should be done as this link states

    EXAMPLE How would I map api/user/create as the code shows above to this format:

    config.Routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/{controller}/{action}/{id}",
    defaults: new { action = "get", id = RouteParameter.Optional });

    Wednesday, April 6, 2016 8:00 PM
  • This is what happens in your snippet:

    HttpConfiguration config = new HttpConfiguration();
    
            //For more information on Web API tracing, see http://go.microsoft.com/fwlink/?LinkId=620686 
            config.EnableSystemDiagnosticsTracing();
            config.MapHttpAttributeRoutes();
    
            new MobileAppConfiguration()
                .UseDefaultConfiguration()
                .ApplyTo(config);
    

    ApplyTo calls MapApiControllers

    https://github.com/Azure/azure-mobile-apps-net-server/blob/master/src/Microsoft.Azure.Mobile.Server/Config/MobileAppConfiguration.cs#L95

    You can check the source, and follow that pattern in your Startup.MobileApp to register custom controllers and routes. 

    I would suggest a different name than DefaultApi, though. We already use "Home", "Tables", and "DefaultApis".  So registering under those names would cause conflicts.

    https://github.com/Azure/azure-mobile-apps-net-server/blob/master/src/Microsoft.Azure.Mobile.Server/Config/RouteNames.cs

    Thursday, April 7, 2016 12:00 AM
  • The snippet is the same that I am using more or less, but I will update my code and try.

    I am aware that the EXAMPLE I showed was not correct. It was meant how do I create the mapping I

    config.route,MapHttpRoute(
    
    /* How do I map my route in this way*/
    /* i.e. api/user/create how is this done correctly*/
    
    )
    I am going to try the other suggestions tonight, thank you so much for the info.


    Thursday, April 7, 2016 6:23 AM