Reputation: 9255
Similar to this question, but for the new ASP.NET Core.
I can override an action's routing name:
[ActionName("Bar")]
public IActionResult Foo() {
Can I do that for a controller, using attribute routing?
[?("HelloController")]
public SomeController : Controller {
It should allow generation of links using tag helpers:
<a asp-controller="some" ... // before
<a asp-controller="hello" ... // after
Upvotes: 10
Views: 20010
Reputation: 58723
Such an attribute does not exist. But you can create one yourself:
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class ControllerNameAttribute : Attribute
{
public string Name { get; }
public ControllerNameAttribute(string name)
{
Name = name;
}
}
Apply it on your controller:
[ControllerName("Test")]
public class HomeController : Controller
{
}
Then create a custom controller convention:
public class ControllerNameAttributeConvention : IControllerModelConvention
{
public void Apply(ControllerModel controller)
{
var controllerNameAttribute = controller.Attributes.OfType<ControllerNameAttribute>().SingleOrDefault();
if (controllerNameAttribute != null)
{
controller.ControllerName = controllerNameAttribute.Name;
}
}
}
And add it to MVC conventions in Startup.cs:
services.AddMvc(mvc =>
{
mvc.Conventions.Add(new ControllerNameAttributeConvention());
});
Now HomeController
Index action will respond at /Test/Index
. Razor tag helper attributes can be set as you wanted.
Only downside is that at least ReSharper gets a bit broken in Razor. It is not aware of the convention so it thinks the asp-controller
attribute is wrong.
Upvotes: 28
Reputation: 12805
It should be the same way that you would do it in ASP.NET WebAPI2 before Core:
[Route("Bar")]
public IActionResult Foo() { }
If you're looking to do it on the Controller level as well, there's a different attribute for that:
[RoutePrefix("ControllerFoo")]
public class MyController() { }
Here is a (non-Microsoft) article that goes over how it should be done in .NET Core.
Upvotes: 2
Reputation: 64121
If you don't want to derive the controller name from the Controller class (Classname minus Controller surfix), then just leave out the [controller]
place holder.
[Route("/api/hello")]
public SomeController : Controller {
[HttpGet]
public IActionResult Get() { }
[HttpGet("something")]
public IActionResult GetSomething() { }
}
The overloads in HttpGet
will set the action name. Doing so however, you can't use generic routes like
routes.MapRoute("default", "api/{controller}/{id?}");
or you have to register them manually there
routes.MapRoute("hello", "api/hello/{id?}", defaults: new { controller = "Hello" });
routes.MapRoute("default", "api/{controller}/{id?}");
Upvotes: 10
Reputation: 777
Here is code we are using
[ApiVersion("1.0")]
[Route("api/v{version:apiVersion}/[controller]")]
public class MembersController : Controller { /* */ }
Upvotes: 3