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

时间:2017-02-20 18:10:41

标签: c# asp.net-core asp.net-core-mvc attributerouting

类似to this question,但对于新的ASP.NET Core。

我可以覆盖操作的路由名称:

[ActionName("Bar")]
public IActionResult Foo() {

我可以使用属性路由为控制器执行此操作吗?

[?("HelloController")]
public SomeController : Controller {

它应该允许使用标记助手生成链接:

<a asp-controller="some" ...      // before
<a asp-controller="hello" ...     // after

4 个答案:

答案 0 :(得分:6)

这样的属性不存在。但你可以自己创建一个:

[AttributeUsage(AttributeTargets.Class)]
public class ControllerNameAttribute : Attribute
{
    public string Name { get; }

    public ControllerNameAttribute(string name)
    {
        Name = name;
    }
}

将其应用于您的控制器:

[ControllerName("Test")]
public class HomeController : Controller
{
}

然后创建自定义控制器约定:

public class ControllerNameAttributeConvention : IControllerModelConvention
{
    public void Apply(ControllerModel controller)
    {
        var controllerNameAttribute = controller.Attributes.OfType<ControllerNameAttribute>().SingleOrDefault();
        if (controllerNameAttribute != null)
        {
            controller.ControllerName = controllerNameAttribute.Name;
        }
    }
}

并将其添加到Startup.cs中的MVC约定:

services.AddMvc(mvc =>
{
    mvc.Conventions.Add(new ControllerNameAttributeConvention());
});

现在HomeController索引操作将在/Test/Index回复。可以根据需要设置Razor标记助手属性。

唯一的缺点是至少ReSharper在Razor中有点破碎。它不知道约定,所以它认为asp-controller属性是错误的。

答案 1 :(得分:3)

如果您不想从Controller类(Classname减去Controller surfix)派生控制器名称,那么只需忽略[Route("/api/hello")] public SomeController : Controller { [HttpGet] public IActionResult Get() { } [HttpGet("something")] public IActionResult GetSomething() { } } 占位符。

HttpGet

routes.MapRoute("default", "api/{controller}/{id?}"); 中的重载将设置操作名称。但是,这样做,你不能使用像

这样的通用路线
routes.MapRoute("hello", "api/hello/{id?}", defaults: new { controller = "Hello" });
routes.MapRoute("default", "api/{controller}/{id?}");

或者您必须在那里手动注册

{{1}}

答案 2 :(得分:2)

以下是我们正在使用的代码

[ApiVersion("1.0")]
[Route("api/v{version:apiVersion}/[controller]")]
public class MembersController : Controller { /* */ }

答案 3 :(得分:1)

它应该与在Core:

之前在ASP.NET WebAPI2中执行它的方式相同
[Route("Bar")]
public IActionResult Foo() { }

如果您也希望在控制器级别上执行此操作,则会有不同的属性:

[RoutePrefix("ControllerFoo")]
public class MyController() { }

Here是一篇(非Microsoft)文章,讨论了如何在.NET Core中完成它。