【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[]{"头条新闻","体育新闻","内娱丑闻","炒股趣闻","生活百事","名场面集锦","都市传说","人品观察报"});}}

经验总结扩展阅读