gilmishal
gilmishal

Reputation: 1992

Creating a different route to a specific action

I am working on an asp.net 5 mvc api, and I am currently working on the Accounts Controller.

since I saw in many different places that there is a convention of using /api/Tokenrouting to a login in a web api. I would like to route to that specific method without the accounts prefix, I would prefer not using a different controller, and I would prefer using Attributes over routing in Startup.cs to avoid confusion in the future.

this is what I have currently

[Route("api/[controller]")]
public class AccountsController : Controller
{
    [HttpPost("login")]
    public async Task<JwtToken> Token([FromBody]Credentials credentials)
    {
     ...
    }

    [HttpPost]
    public async Task CreateUser([FromBody] userDto)
    {
      ...
    }
}

Upvotes: 35

Views: 22712

Answers (3)

zwcloud
zwcloud

Reputation: 4889

from https://learn.microsoft.com/en-us/aspnet/core/mvc/controllers/routing

[Route("[controller]/[action]")]
public class HomeController : Controller
{
    [Route("~/")]
    [Route("/Home")]
    [Route("~/Home/Index")]
    public IActionResult Index()
    {
        return ControllerContext.MyDisplayRouteInfo();
    }

    public IActionResult About()
    {
        return ControllerContext.MyDisplayRouteInfo();
    }
}

In the preceding code, the Index method templates must prepend / or ~/ to the route templates. Route templates applied to an action that begin with / or ~/ don't get combined with route templates applied to the controller.

Upvotes: 2

Felix K.
Felix K.

Reputation: 15663

For ASP.NET Core it seems that the tilde ~ symbol (see accepted answer) is not needed anymore to override the controller's route prefix – instead, the following rule applies:

Route templates applied to an action that begin with a / don't get combined with route templates applied to the controller. This example matches a set of URL paths similar to the default route.

Here is an example:

[Route("foo")]
public class FooController : Controller
{
    [Route("bar")] // combined with "foo" to map to route "/foo/bar"
    public IActionResult Bar()
    {
        // ...
    }

    [Route("/hello/world")] // not combined; maps to route "/hello/world"
    public IActionResult HelloWorld()
    {

    }   
}

Upvotes: 49

Nkosi
Nkosi

Reputation: 247088

With attribute routing you can use a tilde (~) on the Action's route attribute to override the default route of the Controller if needed:

[Route("api/[controller]")]
public class AccountsController : Controller {

    [HttpPost]
    [Route("~/api/token")] //routes to `/api/token`
    public async Task<JwtToken> Token([FromBody]Credentials credentials) {
        ...
    }

    [HttpPost] 
    [Route("users")] // routes to `/api/accounts/users`
    public async Task CreateUser([FromBody] userDto) {
        ...
    }
}

Upvotes: 73

Related Questions