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

【ASP.NET Core】MVC控制器的各种自定义:应用程序约定的接口与模型的更多相关文章

  1. ASP.NET Core 入门教程 4、ASP.NET Core MVC控制器入门

    一.前言 1.本教程主要内容 ASP.NET Core MVC控制器简介 ASP.NET Core MVC控制器操作简介 ASP.NET Core MVC控制器操作简介返回类型简介 ASP.NET C ...

  2. ASP.NET Core 入门笔记5,ASP.NET Core MVC控制器入门

    摘抄自https://www.cnblogs.com/ken-io/p/aspnet-core-tutorial-mvc-controller-action.html 一.前言 1.本教程主要内容 A ...

  3. ASP.NET Core MVC 控制器创建与依赖注入

    本文翻译自<Controller activation and dependency injection in ASP.NET Core MVC>,由于水平有限,故无法保证翻译完全准确,欢 ...

  4. 扒一扒asp.net core mvc控制器的寻找流程

    不太会排版,大家将就看吧. asp.net core mvc和asp.net mvc中都有一个比较有意思的而又被大家容易忽略的功能,控制器可以写在非Web程序集中,比如Web程序集:"MyW ...

  5. asp.net core MVC 控制器,接收参数,数据绑定

    1.参数 HttpRequest HttpRequest 是用户请求对象 QueryString Form Cookie Session Header 实例: public IActionResult ...

  6. Asp.Net Core MVC控制器和视图之间传值

    一.Core MVC中控制器和视图之间传值方式和Asp.Net中非常类似 1.弱类型数据:ViewData,ViewBag 2.强类型数据:@model 二.代码 实例  1.ViewData pub ...

  7. asp.net core mvc基于Redis实现分布式锁,C# WebApi接口防止高并发重复请求,分布式锁的接口幂等性实现

    使用背景:在使用app或者pc网页时,可能由于网络原因,api接口可能被前端调用一个接口重复2次的情况,但是请求内容是一样的.这样在同一个短暂的时间内,就会有两个相同请求,而程序只希望处理第一个请求, ...

  8. ASP.NET Core - ASP.NET Core MVC 的功能划分

    概述 大型 Web 应用比小型 Web 应用需要更好的组织.在大型应用中,ASP.NET MVC(和 Core MVC)所用的默认组织结构开始成为你的负累.你可以使用两种简单的技术来更新组织方法并及时 ...

  9. ASP.NET Core 入门教程 3、ASP.NET Core MVC路由入门

    一.前言 1.本文主要内容 ASP.NET Core MVC路由工作原理概述 ASP.NET Core MVC带路径参数的路由示例 ASP.NET Core MVC固定前/后缀的路由示例 ASP.NE ...

随机推荐

  1. 【MySQL】从入门到掌握4-主键与Unique

    上期:[MySQL]从入门到掌握3-WorkBench 第一章:主键 在实际开发中,我们不会使用用户名字当作主键.   因为当我们用数据库记录学生信息的时候,学生有可能重名! 我们一般会使用是个int ...

  2. C++ | unordered_map 自定义键类型

    C++ unordered_map 使用自定义类作为键类型 C++ unordered_map using a custom class type as the key

  3. Docker安装Redis并使用Another Redis Desktop Manager连接

    Redis简单介绍 Redis全称是Remote DIctionary Service,即远程字典服务.Redis 是一个使用C语言编写的.开源的(遵守 BSD 协议).高性能的.支持网络.可基于内存 ...

  4. 【译】CLR类型加载器设计

    前言 本文翻译自BotR中的一篇,原文链接 Type Loader Design ,可以帮助我们了解CLR的类型加载机制(注意是Type类型,而不是Class类),文中涉及到术语或者容易混淆的地方,我 ...

  5. 【学习笔记】GBDT算法和XGBoost

    前言 这一篇内容我学了足足有五个小时,不仅仅是因为内容难以理解, 更是因为前面CART和提升树的概念和算法本质没有深刻理解,基本功不够就总是导致自己的理解会相互在脑子里打架,现在再回过头来,打算好好总 ...

  6. Elasticsearch:分布式计分

  7. Exporter介绍

    Exporter是什么 广义上讲所有可以向Prometheus提供监控样本数据的程序都可以被称为一个Exporter.而Exporter的一个实例称为target,如下所示,Prometheus通过轮 ...

  8. Css3中自适应布局单位vh、vw

    视口单位(Viewport units) 什么是视口? 在桌面端,视口指的是在桌面端,指的是浏览器的可视区域:而在移动端,它涉及3个视口:Layout Viewport(布局视口),Visual Vi ...

  9. C#-5 类和继承

    一 类继承 继承是使代码可以复用的重要手段,也是面向对象程序设计的核心思想之一.继承呈现了面向对象程序设计的层次结构. 通过继承,我们能以一个已经存在的类为基础来定义一个新类.已存在的类称为基类或父类 ...

  10. 【算法训练营day1】LeetCode704. 二分查找 LeetCode27. 移除元素

    [算法训练营day1]LeetCode704. 二分查找 LeetCode27. 移除元素 LeetCode704. 二分查找 题目链接:704. 二分查找 初次尝试 看到题目标题是二分查找,所以尝试 ...