Combining route mappings in WebApi

Retrocoder picture Retrocoder · Dec 16, 2014 · Viewed 10.5k times · Source

I am using routing in my WebApi Katana application. I have the following two route mappings that work fine. My question is, can I combine these into a single route mapping using optional parameters? I can’t see an obvious way to do it and keep the required functionality. I am new to this and may have missed a technique that my help me achieve this. If the routes have to stay this way then this isn’t a problem.

        config.Routes.MapHttpRoute(
            name: "UnRegister",
            routeTemplate: "api/services/{serviceName}/{location}",
            defaults: new {controller = "MyController", location = RouteParameter.Optional});

        config.Routes.MapHttpRoute(
            name: "UnRegister2",
            routeTemplate: "api/services/{serviceName}/{instanceId}",
            defaults: new { controller = "MyController" });

The required functionality is to unregister a service by supplying the following details:

Servicename
Servicename and location
Servicename and instanceId

Answer

LeftyX picture LeftyX · Dec 16, 2014

In ASP.NET Web API 2 you can use attribute routing and you don't have to define all your routes that way with MapHttpRoute.

The explanation can be found here.

In your Owin Startup you have to enable the attribute routing using MapHttpAttributeRoutes:

public class Startup
{
    public static void Configuration(IAppBuilder app)
    {
        // Configure Web API for self-host. 
        HttpConfiguration config = new HttpConfiguration();

        //  Enable attribute based routing
        config.MapHttpAttributeRoutes();

        app.UseWebApi(config);

    }
}

and your controller should look something like this:

[RoutePrefix("api/service")]
public class ServicesController : ApiController
{
    [HttpGet]
    [Route("{location}")]
    public IHttpActionResult GetByLocation(string location)
    {
        return Ok();
    }

    [HttpGet]
    [Route("{instanceId:int}")]
    public IHttpActionResult GetByInstanceId(int instanceId)
    {
        return Ok();
    }
}

As you can see I've used RoutePrefix to define the endpoint and route constraints to restrict parameters, as suggested in the article. You can even create your own custom constraints.

The article suggest that you have to install the NuGet package Microsoft.AspNet.WebApi.WebHost. That's not necessary aymore.