[英]Override controller name in ASP.NET Core
Similar to this question , but for the new ASP.NET Core. 与此问题类似,但对于新的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
Such an attribute does not exist. 这样的属性不存在。 But you can create one yourself:
但你可以自己创建一个:
[AttributeUsage(AttributeTargets.Class)]
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: 并将其添加到Startup.cs中的MVC约定:
services.AddMvc(mvc =>
{
mvc.Conventions.Add(new ControllerNameAttributeConvention());
});
Now HomeController
Index action will respond at /Test/Index
. 现在
HomeController
Index动作将在/Test/Index
响应。 Razor tag helper attributes can be set as you wanted. 可以根据需要设置Razor标记助手属性。
Only downside is that at least ReSharper gets a bit broken in Razor. 唯一的缺点是至少ReSharper在Razor中有点破碎。 It is not aware of the convention so it thinks the
asp-controller
attribute is wrong. 它不知道约定,所以它认为
asp-controller
属性是错误的。
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. 如果您不想从Controller类派生控制器名称(Classname减去Controller surfix),那么只需省略
[controller]
占位符。
[Route("/api/hello")]
public SomeController : Controller {
[HttpGet]
public IActionResult Get() { }
[HttpGet("something")]
public IActionResult GetSomething() { }
}
The overloads in HttpGet
will set the action name. HttpGet
的重载将设置操作名称。 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?}");
Here is code we are using 这是我们正在使用的代码
[ApiVersion("1.0")]
[Route("api/v{version:apiVersion}/[controller]")]
public class MembersController : Controller { /* */ }
It should be the same way that you would do it in ASP.NET WebAPI2 before Core: 它应该与在Core之前在ASP.NET WebAPI2中执行它的方式相同:
[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: 如果你想在Controller级别上进行操作,那么它有一个不同的属性:
[RoutePrefix("ControllerFoo")]
public class MyController() { }
Here is a (non-Microsoft) article that goes over how it should be done in .NET Core. 这是一篇(非Microsoft)文章,介绍了如何在.NET Core中完成它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.