ASP.NET Web Api Routing Customization

前端 未结 4 1693
刺人心
刺人心 2021-02-19 11:38

I have WebApi controllers that end with the \"Api\" suffix in their names (For ex: StudentsApiController, InstructorsApiController). I do this to easily differentiate my MVC con

相关标签:
4条回答
  • 2021-02-19 12:14

    Following Youssef's comment on muruug's answer would look something like this

    public class ApiControllerSelector : DefaultHttpControllerSelector
    {
        public ApiControllerSelector (HttpConfiguration configuration) : base(configuration) { }
    
        public override string GetControllerName(HttpRequestMessage request)
        {
            return base.GetControllerName(request) + "api";
        }
    }
    
    0 讨论(0)
  • 2021-02-19 12:18

    Now that ASP.NET Web API 2 is out, there is a much less cumbersome way to do more complex routing like that you suggested, by using attribute routing.

    At the top of your controller just add the following attribute:

    [RoutePrefix("api/students")]
    public class StudentsApiController : ApiController
    {
        ...
    }
    

    And then before each API method:

    [Route("{id}"]
    public HttpResponseMessage Get(int id)
    {
        ...
    }
    

    There is a bit of setup required, but the positives of doing routing this way are many. For one, you can put the routing with the controllers and methods that do the actual work, so you're never searching around wondering if you have the right route. Secondly and more importantly, it's much easier to do more complex routing, like having the controller name different from the route name (like you want) or having very complex patterns to match against.

    0 讨论(0)
  • 2021-02-19 12:24

    I think the extensibility point you're looking for is the controller selector. You can create a class that derives from DefaultHttpControllerSelector and overrides the GetControllerName to strip out the "api" part. You can then register this controller selector on your service's configuration Services.

    0 讨论(0)
  • 2021-02-19 12:33

    Following @Youssef Moussaoui's direction I ended up writing the following code that solved the problem.

    public class ApiControllerSelector : DefaultHttpControllerSelector
    {
        public ApiControllerSelector(HttpConfiguration configuration)
            : base(configuration)
        {
        }
    
        public override string GetControllerName(HttpRequestMessage request)
        {
            if (request == null)
                throw new ArgumentNullException("request");
    
            IHttpRouteData routeData = request.GetRouteData();
    
            if (routeData == null)
                return null;
    
            // Look up controller in route data
            object controllerName;
            routeData.Values.TryGetValue("controller", out controllerName);
    
            if (controllerName != null)
                controllerName += "api";
    
            return (string)controllerName;
        }
    }
    

    And register it in Global.asax as

    GlobalConfiguration.Configuration.Services.Replace(typeof(IHttpControllerSelector),
                new ApiControllerSelector(GlobalConfiguration.Configuration));
    
    0 讨论(0)
提交回复
热议问题