侠客行小李 發表於 2025-5-31 09:40:33

ASP.NET Core中ResourceFilter过滤器的实现

<div id="navCategory"><h5 class="catalogue">目录</h5><ul class="first_class_ul"><li><a href="#_label0">1. 什么是&nbsp;ResourceFilter?</a></li><ul class="second_class_ul"><li><a href="#_lab2_0_0">1.1 过滤器概述</a></li><li><a href="#_lab2_0_1">1.2&nbsp;ResourceFilter&nbsp;的生命周期</a></li></ul><li><a href="#_label1">2. 如何实现&nbsp;ResourceFilter?</a></li><ul class="second_class_ul"><li><a href="#_lab2_1_2">2.1 实现&nbsp;IResourceFilter&nbsp;接口</a></li><li><a href="#_lab2_1_3">示例:实现一个简单的日志记录过滤器</a></li><li><a href="#_lab2_1_4">2.2 将&nbsp;ResourceFilter&nbsp;应用于控制器或方法</a></li><li><a href="#_lab2_1_5">2.3 使用依赖注入</a></li></ul><li><a href="#_label2">3.&nbsp;ResourceFilter&nbsp;的使用场景</a></li><ul class="second_class_ul"><li><a href="#_lab2_2_6">3.1 缓存处理</a></li><li><a href="#_lab2_2_7">3.2 日志记录</a></li><li><a href="#_lab2_2_8">3.3 跨域资源共享(CORS)</a></li><li><a href="#_lab2_2_9">3.4 授权检查</a></li></ul><li><a href="#_label3">4.&nbsp;ResourceFilter&nbsp;与其他过滤器的对比</a></li><ul class="second_class_ul"></ul><li><a href="#_label4">5. 总结</a></li><ul class="second_class_ul"></ul></ul></div><p>在现代 Web 开发中,ASP.NET Core 提供了强大的过滤器(Filters)机制,用于在处理请求的不同阶段执行特定的代码逻辑。ASP.NET Core 中的&nbsp;<code>ResourceFilter</code>&nbsp;是一种非常有用的过滤器类型,允许开发人员在请求到达控制器操作方法之前或响应返回之前执行一些操作。在本文中,我们将详细解析&nbsp;<code>ResourceFilter</code>,介绍它的工作原理、使用场景以及如何在实际项目中运用它。</p>
<p class="maodian"><a name="_label0"></a></p><h2>1. 什么是&nbsp;ResourceFilter?</h2>
<p class="maodian"><a name="_lab2_0_0"></a></p><h3>1.1 过滤器概述</h3>
<p>ASP.NET Core 的过滤器是用于在请求和响应处理的不同阶段执行自定义逻辑的一种机制。过滤器在控制器方法执行之前、之后,或者在异常发生时执行。它们可以帮助开发人员对请求进行验证、处理、修改或者进行其他操作。常见的过滤器类型包括:</p>
<ul><li><strong>Authorization Filters(授权过滤器)</strong>:用于身份验证和授权操作。</li><li><strong>Resource Filters(资源过滤器)</strong>:用于资源级的处理,例如缓存、日志记录等。</li><li><strong>Action Filters(操作过滤器)</strong>:用于在控制器动作执行之前和之后执行一些操作。</li><li><strong>Result Filters(结果过滤器)</strong>:用于在控制器动作返回结果后但在返回响应之前进行操作。</li><li><strong>Exception Filters(异常过滤器)</strong>:用于处理在请求处理过程中发生的异常。</li></ul>
<p>在这些过滤器中,<code>ResourceFilter</code>&nbsp;是最早在请求管道中执行的过滤器之一,通常用于处理一些资源相关的操作,比如缓存管理、日志记录等。</p>
<p class="maodian"><a name="_lab2_0_1"></a></p><h3>1.2&nbsp;ResourceFilter&nbsp;的生命周期</h3>
<p><code>ResourceFilter</code>&nbsp;主要有两个方法,它们分别在请求处理的不同阶段执行:</p>
<ul><li><p><code>OnResourceExecuting</code>:当请求到达控制器操作方法之前执行。此时请求已经经过了路由和模型绑定,但还未执行控制器操作方法。在这里,我们可以处理一些请求级别的资源,如缓存、身份验证检查等。</p></li><li><p><code>OnResourceExecuted</code>:当控制器操作方法执行完毕并生成响应之后,响应还没有返回客户端时执行。此时可以执行一些响应后的处理,比如日志记录、缓存处理等。</p></li></ul>
<p class="maodian"><a name="_label1"></a></p><h2>2. 如何实现&nbsp;ResourceFilter?</h2>
<p class="maodian"><a name="_lab2_1_2"></a></p><h3>2.1 实现&nbsp;IResourceFilter&nbsp;接口</h3>
<p>要实现自定义的&nbsp;<code>ResourceFilter</code>,你需要实现&nbsp;<code>IResourceFilter</code>&nbsp;接口或继承&nbsp;<code>ResourceFilterAttribute</code>&nbsp;类。<code>IResourceFilter</code>&nbsp;接口包含两个方法:<code>OnResourceExecuting</code>&nbsp;和&nbsp;<code>OnResourceExecuted</code>,你可以在这些方法中定义需要在请求生命周期中的不同阶段执行的操作。</p>
<p class="maodian"><a name="_lab2_1_3"></a></p><h3>示例:实现一个简单的日志记录过滤器</h3>
<p>假设我们需要创建一个&nbsp;<code>ResourceFilter</code>,用于记录请求的开始和结束时间。下面是一个简单的实现:</p>
<div class="jb51code"><pre class="brush:csharp;">using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Logging;
using System;

public class LogResourceFilter : IResourceFilter
{
    private readonly ILogger&lt;LogResourceFilter&gt; _logger;

    public LogResourceFilter(ILogger&lt;LogResourceFilter&gt; logger)
    {
      _logger = logger;
    }

    // 请求开始时执行
    public void OnResourceExecuting(ResourceExecutingContext context)
    {
      _logger.LogInformation($"Request started at {DateTime.Now}");
    }

    // 请求结束时执行
    public void OnResourceExecuted(ResourceExecutedContext context)
    {
      _logger.LogInformation($"Request ended at {DateTime.Now}");
    }
}
</pre></div>
<p>在这个示例中,<code>LogResourceFilter</code>&nbsp;记录了每个请求的开始和结束时间。<code>OnResourceExecuting</code>&nbsp;方法在请求处理开始时执行,而&nbsp;<code>OnResourceExecuted</code>&nbsp;方法则在请求处理结束后执行。</p>
<p class="maodian"><a name="_lab2_1_4"></a></p><h3>2.2 将&nbsp;ResourceFilter&nbsp;应用于控制器或方法</h3>
<p>创建了&nbsp;<code>LogResourceFilter</code>&nbsp;之后,接下来需要将它应用到控制器或具体的方法上。你可以使用&nbsp;<code>ServiceFilter</code>&nbsp;或&nbsp;<code>TypeFilter</code>&nbsp;特性来应用&nbsp;<code>ResourceFilter</code>。</p>
<p>应用于整个控制器</p>
<div class="jb51code"><pre class="brush:csharp;">
public class HomeController : Controller
{
    public IActionResult Index()
    {
      return View();
    }
}
</pre></div>
<p>应用于控制器方法</p>
<div class="jb51code"><pre class="brush:csharp;">public class HomeController : Controller
{
   
    public IActionResult Index()
    {
      return View();
    }
}
</pre></div>
<p>通过这种方式,你可以确保&nbsp;<code>LogResourceFilter</code>&nbsp;在请求进入控制器方法之前和之后都能执行日志记录操作。</p>
<p class="maodian"><a name="_lab2_1_5"></a></p><h3>2.3 使用依赖注入</h3>
<p><code>ResourceFilter</code>&nbsp;可以依赖注入到控制器或方法中。在 ASP.NET Core 中,依赖注入非常重要,可以让你轻松地管理对象的生命周期。</p>
<p>首先,在&nbsp;<code>ConfigureServices</code>&nbsp;方法中注册&nbsp;<code>LogResourceFilter</code>:</p>
<div class="jb51code"><pre class="brush:csharp;">public void ConfigureServices(IServiceCollection services)
{
    // 注册自定义的 ResourceFilter
    services.AddScoped&lt;LogResourceFilter&gt;();
   
    services.AddControllersWithViews();
}
</pre></div>
<p>然后使用&nbsp;<code>ServiceFilter</code>&nbsp;特性将&nbsp;<code>LogResourceFilter</code>&nbsp;应用到控制器或方法。</p>
<p class="maodian"><a name="_label2"></a></p><h2>3.&nbsp;ResourceFilter&nbsp;的使用场景</h2>
<p><code>ResourceFilter</code>&nbsp;通常用于一些全局的、与请求资源处理相关的操作。以下是一些典型的应用场景:</p>
<p class="maodian"><a name="_lab2_2_6"></a></p><h3>3.1 缓存处理</h3>
<p>你可以在&nbsp;<code>OnResourceExecuting</code>&nbsp;方法中检查请求是否已经被缓存,并返回缓存的结果,避免重复的资源处理。在&nbsp;<code>OnResourceExecuted</code>&nbsp;方法中,你可以对响应进行缓存处理。</p>
<p>示例:简单的缓存检查</p>
<div class="jb51code"><pre class="brush:cpp;">public class CacheResourceFilter : IResourceFilter
{
    public void OnResourceExecuting(ResourceExecutingContext context)
    {
      // 检查是否有缓存的结果
      var cachedResult = CheckCache(context.HttpContext.Request);
      if (cachedResult != null)
      {
            context.Result = cachedResult; // 如果有缓存,直接返回缓存结果
      }
    }

    public void OnResourceExecuted(ResourceExecutedContext context)
    {
      // 如果没有缓存,可以将结果缓存
      if (context.Result != null)
      {
            AddToCache(context.HttpContext.Request, context.Result);
      }
    }

    private object CheckCache(Microsoft.AspNetCore.Http.HttpRequest request)
    {
      // 这里是检查缓存的逻辑
      return null; // 示例中返回 null,实际应该根据请求来检查缓存
    }

    private void AddToCache(Microsoft.AspNetCore.Http.HttpRequest request, object result)
    {
      // 将结果添加到缓存
    }
}
</pre></div>
<p class="maodian"><a name="_lab2_2_7"></a></p><h3>3.2 日志记录</h3>
<p>你可以在请求开始时记录请求的信息,在请求结束时记录响应的状态。这对于监控和调试非常有帮助。</p>
<p class="maodian"><a name="_lab2_2_8"></a></p><h3>3.3 跨域资源共享(CORS)</h3>
<p>在请求到达控制器方法之前,你可以通过&nbsp;<code>ResourceFilter</code>&nbsp;设置跨域资源共享(CORS)策略,动态控制哪些源可以访问你的资源。</p>
<p class="maodian"><a name="_lab2_2_9"></a></p><h3>3.4 授权检查</h3>
<p>尽管通常授权检查是由&nbsp;<code>AuthorizationFilter</code>&nbsp;来完成的,但你也可以在&nbsp;<code>ResourceFilter</code>&nbsp;中进行一些额外的验证。比如,根据请求的路径、参数或头信息做一些自定义的权限校验。</p>
<p class="maodian"><a name="_label3"></a></p><h2>4.&nbsp;ResourceFilter&nbsp;与其他过滤器的对比</h2>
<p><code>ResourceFilter</code>&nbsp;是在请求管道中最早执行的过滤器之一,它通常用于处理资源相关的操作。而其他过滤器如&nbsp;<code>ActionFilter</code>&nbsp;和&nbsp;<code>AuthorizationFilter</code>&nbsp;通常在请求处理的其他阶段执行。</p>
<ul><li><p><code>ResourceFilter</code>:用于处理资源级的操作,如缓存、日志记录、跨域设置等。</p></li><li><p><code>ActionFilter</code>:用于在控制器方法执行前后执行操作,通常用于修改请求或响应数据,或者执行业务逻辑。</p></li><li><p><code>AuthorizationFilter</code>:用于身份验证和授权操作,确保请求具有适当的权限。</p></li><li><p><code>ExceptionFilter</code>:用于捕获异常并进行处理。</p></li></ul>
<p><code>ResourceFilter</code>&nbsp;通常用于请求级别的预处理操作,而&nbsp;<code>ActionFilter</code>&nbsp;则用于处理与具体操作方法相关的任务。</p>
<p class="maodian"><a name="_label4"></a></p><h2>5. 总结</h2>
<p><code>ResourceFilter</code>&nbsp;是 ASP.NET Core 中非常强大的一种过滤器类型,它允许开发人员在请求处理的早期阶段(控制器方法执行之前)进行资源级的处理。通过实现&nbsp;<code>IResourceFilter</code>&nbsp;接口,开发人员可以在请求到达控制器前后执行自定义逻辑,如缓存管理、日志记录、跨域资源共享等。由于&nbsp;<code>ResourceFilter</code>&nbsp;在请求管道中执行的优先级较高,因此它非常适用于一些全局的资源处理操作。</p>
<p>掌握&nbsp;<code>ResourceFilter</code>&nbsp;的使用,可以帮助你更好地控制请求的生命周期,提升应用的性能和可维护性。</p>
頁: [1]
查看完整版本: ASP.NET Core中ResourceFilter过滤器的实现