ASP.NET Core使用Filter和Redis实现接口防重

时光静好 2024-03-04 ⋅ 35 阅读

引言

在Web开发中,接口的重复提交是一个常见的问题。当用户在页面上重复点击提交按钮时,可能会导致系统生成重复的数据或者执行重复的操作。为了避免这种情况,我们可以通过使用Filter和Redis来实现接口防重的功能。

什么是Filter?

Filter是ASP.NET Core中一种用来处理Http请求和响应的中间件。可以通过在Action方法或全局配置中使用Filter来实现身份验证、异常处理、日志记录等功能。

什么是Redis?

Redis是一个开源的内存数据结构存储系统,常用于缓存、消息队列等场景。Redis的特点是高性能、支持持久化、支持多种数据结构等。

实现步骤

第一步:安装ASP.NET Core和Redis

首先,我们需要安装ASP.NET Core和Redis。可以通过以下命令安装:

dotnet new webapi -n MyApi
cd MyApi
dotnet add package StackExchange.Redis

第二步:创建接口防重Filter

在项目中创建一个名为PreventDuplicateRequestFilter的类,继承自ActionFilterAttribute。这个Filter将用来检查请求是否已经处理,如果已经处理,则返回重复请求的错误提示。

using Microsoft.AspNetCore.Mvc.Filters;
using StackExchange.Redis;

public class PreventDuplicateRequestFilter : ActionFilterAttribute
{
    private readonly IDatabase _redisDatabase;

    public PreventDuplicateRequestFilter()
    {
        var redis = ConnectionMultiplexer.Connect("localhost");
        _redisDatabase = redis.GetDatabase();
    }

    public override void OnActionExecuting(ActionExecutingContext context)
    {
        var request = context.HttpContext.Request;
        var requestId = ComputeRequestId(request);

        var isDuplicateRequest = _redisDatabase.StringSet(requestId, "", TimeSpan.FromSeconds(10), When.NotExists);

        if (!isDuplicateRequest)
        {
            // 返回重复请求的错误提示
            context.Result = new BadRequestObjectResult("Duplicate request");
        }
    }

    private string ComputeRequestId(HttpRequest request)
    {
        // 根据请求的url、method和参数等计算一个请求ID
        // 这里可以根据具体的业务需求进行计算
        return $"Request:{request.Path}:{request.Method}:{RequestParamsToString(request)}";
    }

    private string RequestParamsToString(HttpRequest request)
    {
        // 这里将请求的参数转换为字符串,以便计算请求ID
        // 这里可以根据具体的业务需求进行转换
        // 如果请求参数较多,可以考虑对请求参数进行简化或者只计算部分参数
        return "";
    }
}

第三步:在Controller中使用Filter

在需要防重的Controller的Action方法上使用我们创建的PreventDuplicateRequestFilter

[ApiController]
[Route("[controller]")]
public class ApiController : ControllerBase
{
    [HttpGet]
    [ServiceFilter(typeof(PreventDuplicateRequestFilter))]
    public IActionResult Get()
    {
        // 处理请求的逻辑...
        return Ok();
    }
}

第四步:运行测试

启动Redis服务,并运行我们的ASP.NET Core应用程序。然后,通过浏览器、Postman或其他方式访问我们的接口,多次发送相同的请求,查看结果。

结束语

通过使用Filter和Redis,我们可以很方便地实现接口防重的功能。防止用户多次提交相同的请求,提高系统的稳定性和用户体验。当然,具体的实现方案可以根据业务需求进行调整和优化。希望这篇文章对你有所帮助!


全部评论: 0

    我有话说: