Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Route all Web API requests to one controller method

Is it possible to customize ASP.NET Web API's routing mechanism to route all requests to the API to one controller method?

If a request comes in to

www.mysite.com/api/products/

or

www.mysite.com/api/otherResource/7

All would be routed to my SuperDuperController's Get() method?

like image 260
msk Avatar asked Jun 24 '15 09:06

msk


People also ask

How many get methods we can implement in single controller in Web API?

Usually a Web API controller has maximum of five actions - Get(), Get(id), Post(), Put(), and Delete().

Which method is generally used for registering Web API routes?

Web API 2 supports a new type of routing, called attribute routing. As the name implies, attribute routing uses attributes to define routes. Attribute routing gives you more control over the URIs in your web API. For example, you can easily create URIs that describe hierarchies of resources.

What is the difference between MVC routing and Web API routing?

If you are familiar with ASP.NET MVC, Web API routing is very similar to MVC routing. The main difference is that Web API uses the HTTP verb, not the URI path, to select the action. You can also use MVC-style routing in Web API.


2 Answers

I ran into a case where I needed to do this. (Web API 2)

I first looked into creating custom IHttpControllerSelector and IHttpActionSelectors. However, that was a bit of a murky way around. So I finally settled on this dead simple implementation. All you have to do is setup a wildcard route. Example:

public class SuperDuperController : ApiController
{
    [Route("api/{*url}")]
    public HttpResponseMessage Get()
    {
        // url information
        Request.RequestUri
        // route values, including "url"
        Request.GetRouteData().Values
    }
}

Any GET request that starts with "api/" will get routed to the above method. That includes the above mentioned URLs in your question. You will have to dig out information from the Request or context objects yourself since this circumvents automatic route value and model parsing.

The good thing about this is you can still use other controllers as well (as long as their routes don't start with "api/").

like image 104
Kasey Speakman Avatar answered Oct 07 '22 08:10

Kasey Speakman


I don't konw why you would want to do this and I certainly wouldn't recommend routing everything through one controller, however you could achieve this as follows. Assuming you are only ever going to have a resource with an optional id in your calls, add this to your WebApiConfig:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{resource}/{id}",
            defaults: new { controller = "SuperDuper", id = RouteParameter.Optional }
        );
    }
}

Then define your controller method as follows:

public class SuperDuperController : ApiController
{
    public IHttpActionResult Get(string resource, int? id = null)
    {
        return Ok();
    }
}

You would need to decide on an appropriate IHttpActionResult to return for each different type of resource.

Alternatively using Attribute Routing, ensure that config.MapHttpAttributeRoutes() is present in your WebApiConfig and add the following attributes to your controller method:

[RoutePrefix("api")]
public class SuperDuperController : ApiController
{
    [Route("{resource}/{id?}")]
    public IHttpActionResult Get(string resource, int? id = null)
    {
        return Ok();
    }
}
like image 26
Jon Susiak Avatar answered Oct 07 '22 09:10

Jon Susiak