allbetgmaing下载:【asp.net core 系列】10 实战之ActionFilter

时间:3个月前   阅读:30

0.前言

在上一篇中,我们提到了若何建立一个UnitOfWork并通过ActionFilter设置启用。这一篇我们将简朴先容一下ActionFilter以及若何行使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);

上图是这四个方式在一次请求中执行的顺序。在一次请求真正执行之前,想要阻挡这个请求,应该使用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,我们暂且不关注它的父类,只看一下它自己的属性。

  • ActionArguments 示意Action的参数列表,这内里放着种种从用户接到请求参数以及其他中心处置程序添加的参数
  • Controller 示意执行该请求的控制器,在之前我们提过,asp.net core 对于控制器的限制很小,以是控制器什么类型都可能,故而这里使用object作为控制器类型
  • Result 执行效果,正常情况下,在此处获取这个属性的值没有意义。然则我们可以通过修改这个属性的值,来让我们阻挡请求

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,暂且忽略。

  • Canceled 示意是否被设置短路
  • Controller 处置请求的控制器
  • Exception 执行过程中是否发生异常,若是有异常则 有值,否则为Null
  • ExceptionHandled 异常是否被处置
  • Result 此处对Result举行修改不会屏障执行的ActionResult,然则可以向用户隐藏对应的实现

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; }
}
  • Cancel 作废当前效果执行以及后续筛选器的执行
  • Controller 控制器
  • Result 处置效果

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; }
}
  • ActionDescriptor 执行的Action形貌信息,包罗Action的显示名称、一些参数等,详细用到的时刻,再为大伙详细说
  • HttpContext 可以通过这个属性获取此次请求的Request和Response工具
  • ModelState 模子校验信息, 这部分在后续再为小伙伴们细说
  • RouteData 路由信息,asp.net core 在处置请求时剖析出来的路由信息,包罗在程序中修改的路由信息

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);
}

工具类实在本质上就是一次文件写入的方式,自己没什么难度。

不外,这里另有有个小问题,每次挪用都市笼罩原有的文件,另有就是这内里有许多可以优化的地方,小伙伴们可以自己试试去优化一下,让代码更悦目一点。

4 总结

到目前为止,实战系列也有了几篇,许多小伙伴问我能提供一下源码吗?固然,能呀。不外不是现在,容我留个谜底。当主要框架功效完成之后,我就会给小伙伴们发代码的。

实在也是由于现在还没个完整的,开放给小伙伴们也没啥意义。固然了,随着一块敲,也是能实现的哈。要害地方的代码都有。

更多内容烦请关注我的博客《高先生小屋》

,

欧博allbet网址

欢迎进入欧博allbet网址(Allbet Game):www.aLLbetgame.us,欧博官网是欧博集团的官方网站。欧博官网开放Allbet注册、Allbe代理、Allbet电脑客户端、Allbet手机版下载等业务。

上一篇:环球ug代理:法国航空公司设计淘汰8000至10000名员工

下一篇:欧博客户端:郭士强:辽篮的目的照样朝茷a军去