emery.noel
emery.noel

Reputation: 1185

Mixing WebAPI and MVC AttributeRouting with Route Prefix?

I'm pretty new to setting up routes and routing in MVC. At my last job we used attribute routing for our WebAPI stuff, so I'm pretty familiar with that (RoutePrefix, Route, and HttpGet/HttpPost attributes, etc). And I can get my current project to work just fine with attributes.

So now what I want to do is "prefix" all of the webApi routes with "api". So instead of going to mysite/test/hello, I want to go to mysite/api/test/hello.

This is what I have, using only attribute routing, and it works just fine:

[RoutePrefix("Test")]
public class TestController : ApiController
{ ....

  [HttpPost]
  [Route("{message}")]
  public HttpResponse EchoBack(string message)
  {
      // return message ... in this case, "hello"
  }
}

Now, I know I can change the RoutePrefix to "api/Test" (which works 100%), but I don't want to change all my controllers, I would rather be able to perform this by changing the values passed in to config.Routes.MapHttpRoute in WebApiConfig.

Is this possible?

Upvotes: 2

Views: 1881

Answers (1)

Nkosi
Nkosi

Reputation: 247561

What you describe can be done in attribute routing by using what is referred to as a global route prefix.

Referencing this article Global route prefixes with attribute routing in ASP.NET Web API

Create a DirectRouteProvider

public class CentralizedPrefixProvider : DefaultDirectRouteProvider {
    private readonly string _centralizedPrefix;

    public CentralizedPrefixProvider(string centralizedPrefix) {
        _centralizedPrefix = centralizedPrefix;
    }

    protected override string GetRoutePrefix(HttpControllerDescriptor controllerDescriptor) {
        var existingPrefix = base.GetRoutePrefix(controllerDescriptor);
        if (existingPrefix == null) return _centralizedPrefix;

        return string.Format("{0}/{1}", _centralizedPrefix, existingPrefix);
    }
}

To quote article.

The CentralizedPrefixProvider shown above, takes a prefix that is globally prepended to every route. If a particular controller has it’s own route prefix (obtained via the base.GetRoutePrefix method invocation), then the centralized prefix is simply prepended to that one too.

Configure it in the WebAPiConfig like this

config.MapHttpAttributeRoutes(new CentralizedPrefixProvider("api"));

So now for example if you have a controller like this

[RoutePrefix("Test")]
public class TestController : ApiController {
    [HttpPost]
    [Route("{message}")]
    public IHttpActionResult EchoBack(string message) { ... }
}

The above action will be accessed via

<<host>>/api/Test/{message}

where api will be prepended to the controller actions route.

Upvotes: 1

Related Questions