2017-02-20 71 views
1

類似to this question,但用於新的ASP.NET Core。覆蓋ASP.NET核心中的控制器名稱

我可以覆蓋一個動作的路由名稱:

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

我可以這樣做,對於一個控制器,使用屬性路由?

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

應該允許代使用標記助手鍊接:

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

我用[ApiVersion(「1.0」)] [Route(「api/v {version:apiVersion}/[controller]」)]] –

回答

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; 
     } 
    } 
} 

而且它在啓動時加入MVC公約。 cs:

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

現在HomeController索引操作將響應/Test/Index。 Razor標籤助手屬性可以設置爲你想要的。

唯一的缺點是至少ReSharper在Razor中有點受傷。它不知道約定,所以它認爲asp-controller屬性是錯誤的。

+1

這應該在框架中 – grokky

1

應該以同樣的方式,你會做它在ASP.NET WebAPI2核心之前:

[Route("Bar")] 
public IActionResult Foo() { } 

如果您想要在控制器級別上執行此操作,則會有以下不同的屬性:

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

Here是一個(非微軟)文章,詳細介紹了它應該如何在.NET Core中完成。

+0

對於使用標記助手的我不起作用。 – grokky

+0

當你做標籤助手時,它有什麼關係嗎?我有一些「沒有道理」的控制器,但我修改了路徑以使其看起來相關。 – ganders

+0

不幸的是它很重要,因爲我需要重構幾十個視圖。我希望有一種方法可以在一個地方進行重命名。此外,所有控制器的操作都已經指定了路線。我需要這個專門與標籤助手一起工作。 – grokky

2

這裏是我們使用

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

這種情況下控制器的名稱是什麼?我可以使用它來生成鏈接嗎? – grokky

+1

'[controller]'是一個佔位符,它將被控制器類名減去單詞「Controller」,所以「成員」所取代。 – juunas

+0

@juunas絕對正確! –

3

如果你不想從控制器類(類名減去控制器surfix)推導出控制器的名稱,然後就離開了[controller]佔位符碼。

[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?}");