Answered by:
Azure Mobile Apps Custom API .Net backend - Second Controller

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
-
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/- Proposed as answer by Aziel C Epilepsia Wednesday, April 6, 2016 7:52 PM
- Edited by Aziel C Epilepsia Wednesday, April 6, 2016 7:55 PM
- Marked as answer by JOTM123 Thursday, April 7, 2016 5:14 PM
Wednesday, April 6, 2016 7:52 PM
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.
**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/- Proposed as answer by Aziel C Epilepsia Wednesday, April 6, 2016 7:52 PM
- Edited by Aziel C Epilepsia Wednesday, April 6, 2016 7:55 PM
- Marked as answer by JOTM123 Thursday, April 7, 2016 5:14 PM
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 onMapApiControllers
. The mapping should be done as this link statesEXAMPLE 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
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.
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 Iconfig.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