Routing WebAPI 2 Attributes with Non-Working Scopes

I'm having trouble getting the WEBAPI 2 attribute routing to work. The routing scheme I'm looking for is /api/{product}/{controller}/{id-optional}

so /api/Vision/IdCard

. The controllers are in scope and configured as follows:

namespace DataServices.Controllers.Vision
{
     [RoutePrefix("api/vision")]
        public class IdCardController : BaseApiController
        {
            [System.Web.Mvc.RequireHttps]
            [Route("idcard")]
            public IdCardViewModel Get(HttpRequestMessage request)
            {...}

      

Whenever I do this, I get a 404 . I included the namespace as the scope is in its own namespace. Are scopes supported in WEBAPI attribute routing?

EDIT: The WebApiConfig looks like this:

 config.SuppressDefaultHostAuthentication();
            config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));

            // Web API routes
            config.MapHttpAttributeRoutes();

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

      

+3


source to share


4 answers


The scope functionality is not available in the Asp.Net Web API project and is harder to maintain with a custom way, such as a namespace based controller. I have checked many issues with controller and namespace based routing, for example single action method is available on namespace based routing as well as default routing. Thus, the custom implementation does not diminish our requirements.

To solve this problem, we can use a simple way to manage controller routing like:

      //Remove default routing registration      
      /*config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );*/

      

And only use attribute based routing like

[RoutePrefix("api/user/home")]
public class UserHomeController : ApiController
{
     [Route]
     public string Get()
     {
       return "Test user GET";
     }
}

      



And for different area / module controllers

[RoutePrefix("api/admin/home")]
public class AdminHomeController : ApiController
{
     [Route]
     public string Get()
     {
       return "Test admin GET";
     }
}

      

The advantages of this approach are:

  • No need for custom logic like namespace based scope, custom routing handler, so its the best way to code it.
  • You just need to add the [Route] attribute to the action to the API accessibility
+1


source


You need to get an HttpConfiguration instance from the GlobalConfiguration object and call the MapHttpAttributeRoutes () method from the RegisterArea AreaRegistration.cs method.

    public override void RegisterArea(AreaRegistrationContext context) 
    {
        GlobalConfiguration.Configuration.MapHttpAttributeRoutes();

        //... omitted code  
    }

      



This must be done for each Region. Finally, you must remove the config.MapHttpAttributes () method in 'WebApiConfig' or get a duplicate exception.

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        // Web API configuration and services
        config.EnableCors();

        // Configure Web API to use only bearer token authentication.
        config.SuppressDefaultHostAuthentication();
        config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));


        // Web API routes
        //config.MapHttpAttributeRoutes();

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

      

+1


source


Where does an MVC project start? Then I think you should delete the ApiAreaRegistration.cs file generated when the area was created. It is found at the root of your Api area and will conflict with your attribute routes as it will match an MVC route (not WebApi) like "api / {controller} / {action} / {id}" before it finds your specific routes ...

Hope it helps!

0


source


Try playing with the initialization order in Application_Start

this way:

//Config WebAPI(2) where you call config.MapHttpAttributeRoutes();

      

  • GlobalConfiguration.Configure (WebApiConfig.Register);

  • AreaRegistration.RegisterAllAreas ();

  • FilterConfig.RegisterGlobalFilters (GlobalFilters.Filters);
  • RouteConfig.RegisterRoutes (RouteTable.Routes);
  • BundleConfig.RegisterBundles (BundleTable.Bundles);

Ordering is very important (if I reverse the scopeRegister with WebApiConfig => WebAPI 2Routing doesn't work

0


source







All Articles