首页 > 编程 > .NET > 正文

在Asp.Net Core中使用ModelConvention实现全局过滤器隔离

2024-07-10 12:49:41
字体:
来源:转载
供稿:网友

从何说起

这来自于我把项目迁移到Asp.Net Core的过程中碰到一个问题。在一个web程序中同时包含了MVC和WebAPI,现在需要给WebAPI部分单独添加一个接口验证过滤器 IActionFilter ,常规做法一般是写好过滤器后给需要的控制器挂上这个标签,高级点的做法是注册一个全局过滤器,这样可以避免每次手动添加同时代码也更好管理。注册全局过滤器的方式为:

services.AddMvc(options => {  options.Filters.Add(typeof(AccessControlFilter)); });

但这样做会带来一个问题,那就是MVC部分控制器也会受影响,虽然可以在过滤器中进行一些判断来区分哪些是MVC Controller哪些是API Controller,但是平白无故给MVC增加这么一个没用的Filter,反正我是不能忍,所以寻找有没有更好的办法来实现这个功能。

于是ModelConvention(可以翻译为模型约定)闪亮登场。

先认识下ApplicationModel

看一下官方文档是怎么描述应用程序模型(ApplicationModel)的:

ASP.NET Core MVC defines an application model representing the components of an MVC app. You can read and manipulate this model to modify how MVC elements behave. By default, MVC follows certain conventions to determine which classes are considered to be controllers, which methods on those classes are actions, and how parameters and routing behave. You can customize this behavior to suit your app's needs by creating your own conventions and applying them globally or as attributes.

简单一点说,ApplicationModel描述了MVC应用中的各种对象和行为,这些内容包含Application、Controller、Action、Parameter、Router、Page、Property、Filter等等,而Asp.Net Core框架本身内置一套规则(Convention)用来处理这些模型,同时也提供了接口给我们自定义约定来扩展模型以实现更符合需要的应用。

和应用程序模型有关的类都定义在命名空间 Microsoft.AspNetCore.Mvc.ApplicationModels 中,这些模型通过 IApplicationModelProvider 构建出来,Asp.Net Core框架提供的默认Provider是 DefaultApplicationModelProvider 。我们可以编辑这些模型,从而更改它的表现行为,这就要借助它的ModelConvention来实现。

ModelConvention

ModelConvention定义了操作模型的入口,又或者说是一种契约,通过它我们可以对模型进行修改,常用的Convention包括:

IApplicationModelConvention IControllerModelConvention IActionModelConvention IParameterModelConvention IPageRouteModelConvention

这些接口提供了一个共同的方法 Apply ,方法参数是各自的应用程序模型,以 IControllerModelConvention 为例看一下它的定义:

namespace Microsoft.AspNetCore.Mvc.ApplicationModels{ // // 摘要: //  Allows customization of the Microsoft.AspNetCore.Mvc.ApplicationModels.ControllerModel. // // 言论: //  To use this interface, create an System.Attribute class which implements the //  interface and place it on a controller class. Microsoft.AspNetCore.Mvc.ApplicationModels.IControllerModelConvention //  customizations run after Microsoft.AspNetCore.Mvc.ApplicationModels.IApplicationModelConvention //  customizations and before Microsoft.AspNetCore.Mvc.ApplicationModels.IActionModelConvention //  customizations. public interface IControllerModelConvention {  //  // 摘要:  //  Called to apply the convention to the Microsoft.AspNetCore.Mvc.ApplicationModels.ControllerModel.  //  // 参数:  // controller:  //  The Microsoft.AspNetCore.Mvc.ApplicationModels.ControllerModel.  void Apply(ControllerModel controller); }}            
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表