2017-02-20 2 views
1

Ähnlich to this question, aber für den neuen ASP.NET Core.Controller-Name in ASP.NET Core überschreiben

Ich kann eine Aktion des Routing-Namen überschreiben:

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

Kann ich das für einen Controller, mit Attribut-Routing?

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

Es sollte mit Tag-Helfer Generation von Verbindungen erlauben:

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

Ich benutze [Route ("api/v {Version: apiVersion}/[Controller]")] mit [ApiVersion ("1.0")] –

Antwort

6

Ein solches Attribut existiert nicht. Aber man kann man selbst erstellen:

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

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

Wenden Sie es auf Ihrem Controller:

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

Dann eine benutzerdefinierte Controller Konvention erstellen:

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

und fügen Sie es MVC-Konventionen in Startup. cs:

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

Jetzt HomeController Die Indexaktion reagiert auf /Test/Index. Razor-Tag-Helferattribute können beliebig festgelegt werden.

Einziger Nachteil ist, dass zumindest ReSharper in Razor ein wenig gebrochen ist. Es ist sich der Konvention nicht bewusst, daher hält es das Attribut asp-controller für falsch.

+1

Dies sollte im Rahmen sein – grokky

1

Es sollte die gleiche Art und Weise sein, dass Sie es in ASP.NET WebAPI2 vor Kern tun würde:

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

Wenn Sie versuchen, es auch auf der Controller-Ebene zu tun, gibt es ein anderes Attribut dafür:

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

ist ein (nicht-Microsoft) Artikel, der geht, wie es in .NET Core getan werden sollte.

+0

Funktioniert nicht für mich mit Tag-Helfer. – grokky

+0

Ist es wichtig, wenn Sie Tag-Helfer machen?Ich habe einige Controller, die "keinen Sinn ergeben", aber ich habe die Routen geändert, um relevant zu sein. – ganders

+0

Leider ist es wichtig, weil ich Dutzende von Ansichten umgestalten müsste. Ich hatte gehofft, ich könnte einen Umbenennungsbefehl an einem Ort ausführen. Außerdem geben alle Aktionen des Controllers bereits eine Route an. Ich brauche das speziell um mit Tag-Helfern zu arbeiten. – grokky

2

Hier ist Code, den wir

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

Wie lautet der Name des Controllers in diesem Fall? Und könnte ich es zum Generieren von Links verwenden? – grokky

+1

'[Controller]' ist ein Platzhalter, der durch den Controller-Klassennamen minus dem Wort "Controller" ersetzt wird, also "Members". – juunas

+0

@juunas ist absolut richtig! –

3

verwenden Wenn Sie nicht den Namen des Controllers aus der Controller-Klasse ableiten wollen (Klassenname minus-Controller Surfix), dann nur den Halter [controller] Ort auslassen.

[Route("/api/hello")] 
public SomeController : Controller { 
    [HttpGet] 
    public IActionResult Get() { } 

    [HttpGet("something")] 
    public IActionResult GetSomething() { } 
} 

Die Überlastungen in HttpGet wird den Namen der Aktion festgelegt. so jedoch tun, können Sie nicht generische Routen wie

routes.MapRoute("default", "api/{controller}/{id?}"); 

verwenden, oder Sie haben sie registrieren manuell dort

routes.MapRoute("hello", "api/hello/{id?}", defaults: new { controller = "Hello" }); 
routes.MapRoute("default", "api/{controller}/{id?}");