You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET Core 8 MVC中实现全局帖子分类过滤器的方案问询

全局帖子分类过滤器实现方案

需求背景

现有网站帖子分类筛选功能通过FilterController的Index动作实现,需将其改造为全局过滤器,让所有依赖_context.Posts展示数据的控制器,直接使用筛选后的数据集替代原始的_context.Posts。

实现步骤

1. 创建全局Action过滤器

实现一个继承IActionFilter的过滤器类,在请求进入控制器动作前完成帖子筛选,并将结果存入HttpContext.Items供控制器取用:

public class PostCategoryFilter : IActionFilter
{
    private readonly ApplicationDbContext _context;
    private readonly IMemoryCache _cache;

    public PostCategoryFilter(ApplicationDbContext context, IMemoryCache cache)
    {
        _context = context;
        _cache = cache;
    }

    public void OnActionExecuting(ActionExecutingContext context)
    {
        // 从缓存读取当前选中的分类,默认显示全部
        var postCategory = _cache.GetString("CurrentPostCategory") ?? "All";

        IQueryable<Post> filteredPosts = _context.Posts;
        if (postCategory != "All" && !string.IsNullOrEmpty(postCategory))
        {
            filteredPosts = filteredPosts.Where(p => p.PostCategory == postCategory);
        }

        // 将筛选后的数据集存入HttpContext,供后续控制器使用
        context.HttpContext.Items["FilteredPosts"] = filteredPosts;
    }

    public void OnActionExecuted(ActionExecutedContext context)
    {
        // 可选:执行动作后的清理或补充逻辑
    }
}

2. 注册全局过滤器

在Program.cs中配置MVC时,将过滤器添加为全局过滤器:

builder.Services.AddControllersWithViews(options =>
{
    options.Filters.Add<PostCategoryFilter>();
});

3. 简化FilterController逻辑

原FilterController无需再处理筛选逻辑,仅负责更新缓存中的当前分类,然后跳转回来源页:

public async Task<IActionResult> Index(string postCategory)
{
    // 处理空值,默认设为"All"
    var validCategory = string.IsNullOrEmpty(postCategory) ? "All" : postCategory;
    _cache.Set("CurrentPostCategory", validCategory);

    // 跳转回来源页,无来源则跳主页
    string refererUrl = Request.Headers["Referer"].ToString();
    return Redirect(string.IsNullOrEmpty(refererUrl) ? "/" : refererUrl);
}

4. 修改业务控制器使用筛选后的数据

将控制器中原本调用_context.Posts的地方,替换为从HttpContext.Items获取的筛选数据集:

[HttpGet]
public async Task<IActionResult> Index()
{
    var filteredPosts = HttpContext.Items["FilteredPosts"] as IQueryable<Post>;
    return View(await filteredPosts.ToListAsync());
}

5. 可选:封装扩展方法简化调用

为HttpContext编写扩展方法,避免控制器中重复的类型转换:

public static class HttpContextExtensions
{
    public static IQueryable<Post> GetFilteredPosts(this HttpContext context)
    {
        return context.Items["FilteredPosts"] as IQueryable<Post> 
            ?? throw new InvalidOperationException("全局帖子分类过滤器未正确初始化");
    }
}

控制器中即可简化为:

[HttpGet]
public async Task<IActionResult> Index()
{
    return View(await HttpContext.GetFilteredPosts().ToListAsync());
}

内容的提问来源于stack exchange,提问作者ZNAXNOR

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 23:19:56