【ASP.NET Core】MVC控制器的各種自定義:應用程序約定的接口與模型

從本篇起,老週會連發N篇水文,總結一下在 MVC 項目中控制器的各種自定義配置。

本文內容相對輕鬆,重點討論一下 MVC 項目中的各種約定接口。畢竟你要對控制器做各種自定義時,多數情況會涉及到約定接口。約定接口的結構都差不多,均包含一個 Apply 方法,實現類需要通過這個方法修改關聯的模型設置。

這些約定接口是按層次來定義的,下面咱們來扒一下。

a、IApplicationModelConvention:此接口可控制的面最廣,屬於應用程序層面。它對應的模型類是 ApplicationModel。該類有個重要屬性—— Controllers,通過它你能獲取到當前應用程序已發現和識別的所有控制器信息。每個控制器也有自己的模型類:ControllerModel。

b、IControllerModelConvention:此接口只應用於控制器層面,而不是整個應用程序。對應的模型類就是上面提到過的 ControllerModel。ControllerType屬性可以獲取控制器類的 Type 信息,而 ControllerName 屬性最有用,因爲可以改變默認的控制器命名。Actions 屬性返回此控制器中所有操作方法(Action)列表。

c、IActionModelConvention:這個接口只應用於操作方法。對應的模型類是 ActionModel。通過 ActionName 屬性可以修改操作方法的名稱。當然,操作方法的名稱可以用 ActionNameAttribute 特性類來定義。

d、IParameterModelConvention:此接口只能自定義操作方法的參數,對應的模型類是 ParameterModel。

e、IPageApplicationModelConvention、IPageHandlerModelConvention、IPageRouteModelConvention:這些接口是用在 Razor Pages 上的,也可以實現一些自定義行爲。

按照需求實現對應的接口。對於應用程序層面的設置,將實現相關約定接口的類實例添加到 MvcOptions.Conventions 集合中。如果實現了 IControllerModelConvention 接口的類實例添加到 Conventions 集合中,那麼它會被應用到所有控制器上。如果只想用到特定的控制器上,應將實現類定義爲特性類,然後應用程序目標控制器上。

好了,理論的東西老周就不長篇大吹了,畢竟也不是老周的特長。只要你瞭解以上各接口和相關模型類,基本上就能運用了。

下面咱們做個很實在的演示:寫一個特性類(ControllerNameAttribute),用來給控制器設置名稱。既然是針對控制器的,約定接口應選擇 IControllerModelConvention。實現代碼如下:

[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
public class ControllerNameAttribute : Attribute, IControllerModelConvention
{
    // 私有字段
    private readonly string _name;

    // 構造函數
    public ControllerNameAttribute(string name)
    {
        // 自定義的控制器名稱就是這樣傳遞的
        _name = name;
    }

    // 這是實現接口的方法
    public void Apply(ControllerModel controller)
    {
        // 修改控制器名稱
        controller.ControllerName = _name;
    }
}

這個類的邏輯很䜭智,通過構造函數的參數來傳遞自定義的控制器名稱,然後存在 _name 私有字段中。在Apply方法中,把 _name 字段賦值給 ControllerName屬性,就完成控制器名稱的修改了。

這個特性類用於控制器,它是一個類,所以 AttributeTargets 選用 Class。咱們創建一個新控制器,然後用 ControllerNameAttribute 來設置控制器的名稱。

    [ControllerName("XinWen")]
    public class NewsController : Controller
    {
        [ActionName("catelogs")]
        public IActionResult GetCates()
        {
            return Ok(new string[]
            {
                "頭條新聞",
                "體育新聞",
                "內娛醜聞",
                "炒股趣聞",
                "生活百事",
                "名場面集錦",
                "都市傳說",
                "人品觀察報"
            });
        }
    }

默認的時候,控制器名稱與類名相同(有 Controller 後綴的會去掉),即 News。咱們應用剛定義的特性類 ControllerNameAttribute 將控制器命名爲 XinWen。操作方法 GetCates 也被重命爲 catelogs。

ActionNameAttribute 是 .NET 內置已有的類型,我們可以直接用。ControllerNameAttribute 非內置,所以咱們要自己來實現。

 

下面代碼初始化應用程序。

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
var app = builder.Build();

app.MapControllerRoute("app", "{controller}/{action}");

app.Run();

 

程序運行後,訪問 /xinwen/catelogs,就能看到結果了。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章