简体   繁体   English

覆盖ASP.NET Core中的控制器名称

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM