首页 > 数据库 >asp.net dotnet razor page mvc 过滤器 数据验证过滤器 数据库事务过滤器

asp.net dotnet razor page mvc 过滤器 数据验证过滤器 数据库事务过滤器

时间:2024-11-03 16:43:12浏览次数:1  
标签:razor asp Task 处理程序 context 过滤器 方法 页面

asp.net dotnet razor page mvc 过滤器 数据验证过滤器 数据库事务过滤器

Program.cs注册过滤器

services.AddRazorPages(opt =>
        {
            opt.Conventions.ConfigureFilter(new DbContextTransactionPageFilter());
            opt.Conventions.ConfigureFilter(new ValidatorPageFilter());
        });

在Program.cs中注册razorpage的过滤器

DbContextTransactionPageFilter过滤器

  • 这个过滤器主要用于处理数据库事务相关的操作。从DbContextTransactionPageFilter类的代码可以看到,它在OnPageHandlerExecutionAsync方法中实现了事务的开始、提交和回滚逻辑

  • ValidatorPageFilter过滤器

IAsyncPageFilter接口

#region Assembly Microsoft.AspNetCore.Mvc.RazorPages, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60
// D:\.nuget\packages\microsoft.aspnetcore.app.ref\6.0.30\ref\net6.0\Microsoft.AspNetCore.Mvc.RazorPages.dll
#endregion
#nullable enable
using System.Threading.Tasks;
namespace Microsoft.AspNetCore.Mvc.Filters
{
    //
    // Summary:
    //     一个异步环绕页面处理方法执行的过滤器。这个过滤器仅在装饰在处理程序类型上时执行,而不在单个处理程序方法上执行。
    public interface IAsyncPageFilter : IFilterMetadata
    {
        // Summary:
        //     在模型绑定完成之后,在处理程序方法被调用之前异步调用。
        // Parameters:
        //   context:
        //     是Microsoft.AspNetCore.Mvc.Filters.PageHandlerExecutingContext类型。
        //   next:
        //     是Microsoft.AspNetCore.Mvc.Filters.PageHandlerExecutionDelegate类型。被调用来执行下一个页面过滤器或处理程序方法本身。
        // Returns:
        //     一个System.Threading.Tasks.Task,完成时表示过滤器已执行。
        Task OnPageHandlerExecutionAsync(PageHandlerExecutingContext context, PageHandlerExecutionDelegate next);
        // Summary:
        //     在处理程序方法被选择之后,但在模型绑定发生之前异步调用。
        // Parameters:
        //   context:
        //     是Microsoft.AspNetCore.Mvc.Filters.PageHandlerSelectedContext类型。
        // Returns:
        //     一个System.Threading.Tasks.Task,完成时表示过滤器已执行。
        Task OnPageHandlerSelectionAsync(PageHandlerSelectedContext context);
    }
}

这段C# 代码定义了一个名为IAsyncPageFilter的接口,它位于Microsoft.AspNetCore.Mvc.Filters命名空间中。该接口用于在ASP.NET Core的MVC框架中对Razor Pages的处理过程进行拦截和过滤。

  1. 接口定义和继承关系

    • IAsyncPageFilter接口继承自IFilterMetadata接口。IFilterMetadata是一个标记接口,用于表示某个类型是一个过滤器相关的元数据类型。
  2. 方法说明

    • OnPageHandlerExecutionAsync方法

      • 在模型绑定完成之后,在页面处理程序方法被调用之前执行。它接收两个参数:PageHandlerExecutingContext类型的contextPageHandlerExecutionDelegate类型的next。其中context包含了当前页面处理执行的上下文信息,next是一个委托,用于执行下一个页面过滤器或者直接执行页面处理程序方法本身。该方法返回一个Task,当这个Task完成时,表示这个过滤器的执行逻辑已经完成。
    • OnPageHandlerSelectionAsync方法

      • 在页面处理程序方法被选择之后,但在模型绑定发生之前执行。它接收一个PageHandlerSelectedContext类型的context参数,该参数包含了页面处理程序被选择的相关上下文信息。该方法同样返回一个Task,当Task完成时,表示过滤器在这个阶段的执行已经完成。

总的来说,这个接口定义了在Razor Pages处理过程中的两个关键阶段(处理程序方法选择之后和执行之前)可以进行异步操作的规范,使得开发人员可以在这些阶段插入自定义的逻辑,比如进行权限验证、日志记录、修改模型状态等操作。

DbContextTransactionPageFilter过滤器

public class DbContextTransactionPageFilter : IAsyncPageFilter
{
    public Task OnPageHandlerSelectionAsync(PageHandlerSelectedContext context) => Task.CompletedTask;

    public async Task OnPageHandlerExecutionAsync(PageHandlerExecutingContext context, PageHandlerExecutionDelegate next)
    {
        var dbContext = context.HttpContext.RequestServices.GetRequiredService<SchoolContext>();
        try
        {
            await dbContext.BeginTransactionAsync();
            var actionExecuted = await next();
            if (actionExecuted.Exception != null && !actionExecuted.ExceptionHandled)
            {
                dbContext.RollbackTransaction();
            }
            else
            {
                await dbContext.CommitTransactionAsync();
            }
        }
        catch (Exception)
        {
            dbContext.RollbackTransaction();
            throw;
        }
    }
}

以下是对DbContextTransactionPageFilter类的详细分析:

  1. 类的定义和接口实现

    • DbContextTransactionPageFilter类实现了IAsyncPageFilter接口,这意味着它可以在异步的Razor页面处理过程中执行过滤逻辑。
  2. 方法分析

    • OnPageHandlerSelectionAsync方法

    • 代码实现为public Task OnPageHandlerSelectionAsync(PageHandlerSelectedContext context) => Task.CompletedTask;

    • 这个方法在页面处理程序被选择时调用,但在这里它没有执行任何实际的逻辑,只是直接返回一个已完成的任务,表示不需要在这个阶段进行任何处理。

    • OnPageHandlerExecutionAsync方法

      • 这是该过滤器的核心方法,用于处理页面请求的执行过程中的事务逻辑。

      • 首先获取SchoolContext实例:

      • 通过var dbContext = context.HttpContext.RequestServices.GetRequiredService<SchoolContext>();从当前的HttpContext的服务提供者中获取SchoolContext实例,这个实例将用于数据库操作和事务管理。

      • 然后开始事务:

      • 调用await dbContext.BeginTransactionAsync();开始一个数据库事务。如果当前已经存在一个未完成的事务(通过_currentTransaction字段判断),则直接返回,不会重复开启事务。

      • 接着执行页面处理程序并处理结果:

      • 通过var actionExecuted = await next();执行下一个过滤器或页面处理程序,并获取执行结果。

      • 如果执行过程中发生异常并且没有被处理(即actionExecuted.Exception!= null &&!actionExecuted.ExceptionHandled),则调用dbContext.RollbackTransaction();回滚事务。

      • 如果没有发生异常或者异常已经被处理,则调用await dbContext.CommitTransactionAsync();提交事务。

      • 最后处理事务对象:

      • 在提交或回滚事务之后,无论事务是否成功完成,都会在finally块中检查_currentTransaction是否为null。如果不为null,则调用_currentTransaction.Dispose();释放事务资源,并将_currentTransaction设置为null,以便下次可以重新开启新的事务。

  3. 配置方式

  • 通过opt.Conventions.ConfigureFilter(new DbContextTransactionPageFilter());DbContextTransactionPageFilter过滤器添加到Razor Pages的过滤器集合中。这样,在每个Razor页面的请求处理过程中,都会经过这个过滤器来处理数据库事务。

ValidatorPageFilter过滤器

public class ValidatorPageFilter : IPageFilter
{
    public void OnPageHandlerSelected(PageHandlerSelectedContext context){}
    public void OnPageHandlerExecuting(PageHandlerExecutingContext context)
    {
        if (!context.ModelState.IsValid)
        {
            if (context.HttpContext.Request.Method == "GET")
            {
                var result = new BadRequestResult();
                context.Result = result;
            }
            else
            {
                var result = new ContentResult();
                var content = JsonConvert.SerializeObject(context.ModelState,
                    new JsonSerializerSettings
                    {
                        ReferenceLoopHandling = ReferenceLoopHandling.Ignore
                    });
                result.Content = content;
                result.ContentType = "application/json";

                context.HttpContext.Response.StatusCode = 400;
                context.Result = result;
            }
        }
    }
    public void OnPageHandlerExecuted(PageHandlerExecutedContext context){}
}
  1. 类的定义和接口实现

    • ValidatorPageFilter类位于ContosoUniversity.Infrastructure命名空间下,实现了IPageFilter接口。IPageFilter接口定义了在页面处理过程中的三个关键阶段(处理程序方法选择、执行前、执行后)可以进行操作的方法。
  2. 方法分析

    • OnPageHandlerSelected方法
      • 该方法在页面处理程序方法被选择时调用,但在这里它没有执行任何实际的逻辑,为空方法。
    • OnPageHandlerExecuting方法
      • 这是该过滤器的核心方法,用于在页面处理程序执行前验证模型的有效性。
      • 首先检查context.ModelState.IsValid,如果模型状态无效:
        • 当请求方法是GET时,创建一个BadRequestResult实例,并将其设置为context.Result。这意味着如果是GET请求且模型验证失败,将返回一个400 Bad Request响应给客户端。
        • 当请求方法不是GET时,创建一个ContentResult实例。
        • context.ModelState序列化为JSON字符串,使用JsonConvert.SerializeObject方法,并设置ReferenceLoopHandling = ReferenceLoopHandling.Ignore来避免循环引用问题。
        • 将序列化后的JSON字符串设置为ContentResultContent属性,将ContentType属性设置为application/json,并将HttpContext.Response.StatusCode设置为400,最后将ContentResult设置为context.Result。这意味着对于非GET请求且模型验证失败,将返回一个包含模型验证错误信息的400 Bad Request响应,格式为JSON。
    • OnPageHandlerExecuted方法
      • 该方法在页面处理程序执行后调用,但在这里它没有执行任何实际的逻辑,为空方法。

在整个项目中,这个过滤器通过services.AddRazorPages(opt => { opt.Conventions.ConfigureFilter(new ValidatorPageFilter()); });被注册到Razor Pages的过滤器集合中。这样,在每个Razor页面的请求处理过程中,都会经过这个过滤器来验证模型的有效性,确保只有在模型验证通过的情况下才会继续执行页面处理程序的核心逻辑,从而提高了应用程序的稳定性和数据的准确性。

标签:razor,asp,Task,处理程序,context,过滤器,方法,页面
From: https://www.cnblogs.com/zhuoss/p/18523606

相关文章

  • asp.net MiniProfiler 性能分析工具
    asp.netMiniProfiler性能分析工具1.依赖包这里使用了MiniProfiler.AspNetCore.Mvc和MiniProfiler.EntityFrameworkCore两个依赖包。从ContosoUniversity.csproj文件中可以看到相关的引用:<PackageReferenceInclude="MiniProfiler.AspNetCore.Mvc"Version="4.2.22"/><Pa......
  • LLaVA-UHD: an LMM Perceiving Any Aspect Ratio and High-Resolution Images
    传统的大多模态模型(LargeMultimodalModel,LMM)关注于固定的尺寸和有限的分辨率。本文以GPT-4V和LLaVa-1.5为代表,揭示了视觉编码策略的根本性系统缺陷。本文指出大多模态模型可以有效地感知任何长宽比和高分辨率的图像。概述为了实现LMM模型在多种长宽比和高分辨率的图像感......
  • vue 中的过滤器filters使用详解
    Vue中的过滤器1.过滤器是什么在Vue2中,过滤器(filters)是用于对数据进行格式化的小型工具,主要用于模板表达式,方便处理文本展示时的格式化工作。过滤器不会改变原始数据,只影响数据的显示方式。2.应用场景文本格式化:如将字符串首字母大写或将全局文本转为大写。日期格......
  • 【C++】布隆过滤器的概念与特点解析
    目录00.引入01.布隆过滤器的概念特点1:极低的内存消耗特点2:快速查询特点3:假阳性误判(禁止删除)02.布隆过滤器的底层实现00.引入上一篇博客介绍了位图这一数据结构,它可以在大量整数中快速查找某一数据是否存在,并且内存占用率很低(例如,查找40亿个整数只需0.5G空间)。博客链......
  • Spring常用过滤器(Filter)-SecurityContextHolderAwareRequestFilter
    SecurityContextHolderAwareRequestFilter:使HttpServletRequestWrapper能够感知SecurityContextHolder的过滤器。1.1功能概述:1.1.1SecurityContextHolderAwareRequestFilter通过Wrapper/Decorator模式对HttpServletRequest进行包装,使其具备访问SecurityContextHolder中安全......
  • 「漏洞复现」F22服装管理软件系统 openfile.aspx 任意文件读取漏洞
    0x01 免责声明请勿利用文章内的相关技术从事非法测试,由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,作者不为此承担任何责任。工具来自网络,安全性自测,如有侵权请联系删除。本次测试仅供学习使用,如若非法他用,与平台和本文作者无关,需......
  • 一个简单的 ASP.NET Core 依赖注入例子,提高代码的可维护性和可扩展性
    前言:什么是依赖注入依赖注入可以提高代码的可维护性、可测试性、可替换性和可扩展性,降低组件之间的耦合度,使得代码更加清晰和灵活,ASP.NETCore提供了内置的依赖注入容器,可以帮助我们轻松地将服务注册到容器中。本文主要通过一个简单的例子来阐述ASP.NETCore依赖注入的使用......
  • Asp.net 使用FluentScheduler
     1.安装包:Install-PackageFluentScheduler2.  Global.asax添加JobManager.Initialize(newMyRegister());3.添加类 publicclassMyRegister:Registry{publicMyRegister(){//ScheduleanIJobtorunataninte......
  • 界面控件DevExpress JS & ASP.NET Core v24.1亮点 - 支持Angular 18
    DevExtreme拥有高性能的HTML5/JavaScript小部件集合,使您可以利用现代Web开发堆栈(包括React,Angular,ASP.NETCore,jQuery,Knockout等)构建交互式的Web应用程序。从Angular和Reac,到ASP.NETCore或Vue,DevExtreme包含全面的高性能和响应式UI小部件集合,可在传统Web和下一代移动应用程序中......
  • 推荐一个 ASP.NET Core 的轻量级插件框架
    前言本文将介绍一个专为ASP.NETCore设计的轻量级插件框架——PluginCore,该框架不仅能够简化插件的开发与集成,还能大幅提高开发效率。另外,还将简要介绍相关的前端技术和SDK支持,帮助我们快速上手。项目介绍PluginCore是一个轻量级插件框架,通过最小化的配置简化插件的集成与管理......