asp.net core 中ActionFilter如何使用

发布时间:2021-07-15 14:20:08 作者:Leah
来源:亿速云 阅读:218

今天就跟大家聊聊有关asp.net core 中ActionFilter如何使用,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。

1. ActionFilter 介绍

ActionFilter全称是ActionFilterAttribute,我们根据微软的命名规范可以看出这是一个特性类,看一下它的声明:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
public abstract class ActionFilterAttribute : Attribute, IActionFilter, IFilterMetadata, IAsyncActionFilter, IAsyncResultFilter, IOrderedFilter, IResultFilter
 

这是一个允许标注在类和方法上的特性类,允许多个标记,标注之后子类会继承父类的特性。然后,这个类是一个抽象类,所以我们可以通过继承ActionFilterAttribute来编写自己的ActionFilter。

 

1.1 ActionFilter的四个方法

对于一个ActionFilter而言,最重要的是它的四个方法:

public virtual void OnActionExecuted(ActionExecutedContext context);
public virtual void OnActionExecuting(ActionExecutingContext context);

public virtual void OnResultExecuted(ResultExecutedContext context);
public virtual void OnResultExecuting(ResultExecutingContext context);
 

asp.net core 中ActionFilter如何使用

上图是这四个方法在一次请求中执行的顺序。在一次请求真正执行之前,想要拦截这个请求,应该使用OnActionExecuting

为什么单独说这个呢?因为这个方法的出镜率很高,大多数时候都会使用这个方法进行请求过滤。

 

1.2 在ActionFilter中我们能做什么

我们来简单介绍一下,四个方法中的四种上下文类型,看一看里面有哪些我们可以利用的方法:

 

1.2.1 ActionExecutingContext

这是一个Action执行前的上下文,表示Action并未开始执行,但是已经获取到了控制器实例:

public class ActionExecutingContext : FilterContext
{
   public virtual IDictionary<string, object> ActionArguments { get; }
   public virtual object Controller { get; }
   public virtual IActionResult Result { get; set; }
}
 

ActionExecutingContext继承自FilterContext,我们暂且不关注它的父类,只看一下它自己的属性。

 

1.2.2 ActionExecutedContext

ActionExecutedContext 表示Action执行完成后的上下文,这时候Action已经执行完成,我们可以通过这个获取Action执行结果:

public class ActionExecutedContext : FilterContext
{
   public virtual bool Canceled { get; set; }
   public virtual object Controller { get; }
   public virtual Exception Exception { get; set; }
   public virtual ExceptionDispatchInfo ExceptionDispatchInfo { get; set; }
   public virtual bool ExceptionHandled { get; set; }
   public virtual IActionResult Result { get; set; }
}
 

同样,继承自FilterContext,暂且忽略。

 

1.2.3 ResultExecutingContext

这是在Result渲染之前执行的上下文,这时候Action已经执行完毕,正准备渲染Result:

public class ResultExecutingContext : FilterContext
{
   public virtual bool Cancel { get; set; }
   public virtual object Controller { get; }
   public virtual IActionResult Result { get; set; }
}
  

1.2.4 ResultExecutedContext

Result已经执行完成了,获取执行结果上下文:

public class ResultExecutedContext : FilterContext
{
   public virtual bool Canceled { get; set; }
   public virtual object Controller { get; }
   public virtual Exception Exception { get; set; }
   public virtual ExceptionDispatchInfo ExceptionDispatchInfo { get; set; }
   public virtual bool ExceptionHandled { get; set; }
   public virtual IActionResult Result { get; }
}
 

这个类与 ActionExecutedContext类似,就不做介绍了。

 

1.2.5 FilterContext

在上面的四个上下文都继承自 FilterContext,那么我们来看一下FilterContext中有哪些属性或者方法:

public abstract class FilterContext : ActionContext
{
   public virtual IList<IFilterMetadata> Filters { get; }
   public TMetadata FindEffectivePolicy<TMetadata>() where TMetadata : IFilterMetadata;
}
 

可以看到FilterContext继承了另一个ActionContext的类。小伙伴们应该对这个类要有一定的概念,这个类是Action的上下文类。它完整存在于一个Action的生命周期,所以有时候可以通过ActionContext进行Action级的数据传递(不推荐)。

那么,继续让我们回过头来看看ActionContext里有什么:

public class ActionContext
{
   public ActionDescriptor ActionDescriptor { get; set; }
   public HttpContext HttpContext { get; set; }
   public ModelStateDictionary ModelState { get; }
   public RouteData RouteData { get; set; }
}
  

2. 使用ActionFilter

在《【asp.net core 系列】9 实战之 UnitOfWork以及自定义代码生成》也就是上一篇中,介绍到了ActionFilter与普通特性类一致,可以通过标注控制器然后启用该ActionFilter。

因为大多数情况下,一个ActionFilter并不会仅仅局限于一个控制器,而是应用于多个控制器。所以这时候,我们通常会设置一个基础控制器,在这个控制器上进行标注,然后让子类继承这个控制器。通过这种方式来实现一次声明多次使用。

当然,在asp.net core 中添加了另外的一种使用ActionFilter的方式,Setup.cs中

public void ConfigureServices(IServiceCollection services)
{
   services.AddControllersWithViews();
}
 

默认是这样的,我们可以通过设置参数来添加一个全局应用的Filter,例如说我们上一篇中创建的 UnitOfWorkFilterAttribute:

services.AddControllersWithViews(options=>
{
   options.Filters.Add<UnitOfWorkFilterAttribute>();
});
 

通过这种方式可以启用一个全局ActionFilter。如果需要使用asp.net core的默认依赖注入可以使用 AddService进行配置。(依赖注入的内容在后续会讲解)。

 

3. 工具类生成

继续上一篇遗留的内容:

public static void CreateEntityTypeConfig(Type type)
{
   var targetNamespace = type.Namespace.Replace("Data.Models", "");
   if (targetNamespace.StartsWith("."))
   {
       targetNamespace = targetNamespace.Remove(0);
   }
   var targetDir = Path.Combine(new[] { CurrentDirect, "Domain.Implements", "EntityConfigures" }.Concat(
       targetNamespace.Split('.')).ToArray());

   if (!Directory.Exists(targetDir))
   {
       Directory.CreateDirectory(targetDir);
   }
   var baseName = type.Name.Replace("Entity", "");
   if (!string.IsNullOrEmpty(targetNamespace))
   {
       targetNamespace = $".{targetNamespace}";
   }

   var file = $"using {type.Namespace};" +
       $"\r\nusing Microsoft.EntityFrameworkCore;" +
       $"\r\nusing Microsoft.EntityFrameworkCore.Metadata.Builders;" +
       $"\r\nnamespace Domain.Implements.EntityConfigures{targetNamespace}" +
       "\r\n{" +
       $"\r\n\tpublic class {baseName}Config : IEntityTypeConfiguration<{type.Name}>" +
       "\r\n\t{" +
       "\r\n\t\tpublic void Configure(EntityTypeBuilder<SysUser> builder)" +
       "\r\n\t\t{" +
       $"\r\n\t\t\tbuilder.ToTable(\"{baseName}\");" +
       $"\r\n\t\t\tbuilder.HasKey(p => p.Id);" +
       "\r\n\t\t}\r\n\t}\r\n}";
   File.WriteAllText(Path.Combine(targetDir, $"{baseName}Config.cs"), file);
}

看完上述内容,你们对asp.net core 中ActionFilter如何使用有进一步的了解吗?如果还想了解更多知识或者相关内容,请关注亿速云行业资讯频道,感谢大家的支持。

推荐阅读:
  1. 解析Asp.net使用Session的方法
  2. 如何理解asp.net mvc core管道及拦截器

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

asp.net core

上一篇:ASP.NE中怎么实现RSA分段加密

下一篇:JavaScript中队列有什么用

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》