绑定完请刷新页面
取消
刷新

分享好友

×
取消 复制
【ASP.NET Core】MVC控制器的各种自定义:应用程序约定的接口与模型
2022-11-18 10:34:51

从本篇起,老周会连发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,就能看到结果了。

分享好友

分享这个小栈给你的朋友们,一起进步吧。

.NET中大型研发必备
创建时间:2022-04-09 00:21:16
本系列文章适合有初/.NET知识的同学阅读(请在电脑上打开页面,获取更好的阅读效果)。 (1)本系列文章,旨在讲述研发一个中大型项目所需要了解的一系列“基本构件”,并提供这些“基本构件”在全网的【简单】、【快速】使用方法!!(并不深究技术原理) (2)通过阅读本系列文章,能让你在“正规”项目研发方面快速入门+进阶,并能达成“小团队构建大网站”的目的。 (3)本系列文章采用的技术,已成功应用到人工智能、产业互联网、社区电商、游戏、金融风控、智慧医疗、等项目上。
展开
订阅须知

• 所有用户可根据关注领域订阅专区或所有专区

• 付费订阅:虚拟交易,一经交易不退款;若特殊情况,可3日内客服咨询

• 专区发布评论属默认订阅所评论专区(除付费小栈外)

栈主、嘉宾

查看更多
  • 红色侦察兵
    栈主

小栈成员

查看更多
  • miemieMIA
  • LCR_
  • xsy028
  • ?时光与海?
戳我,来吐槽~