在 ASP.NET Core 8 MVC 中创建全局过滤器

问题描述 投票:0回答:1

我的网站中有帖子类别。我创建了一个下拉过滤器,可以根据所选类别过滤我的帖子。

过滤器是作为控制器操作方法创建的,但我想将其设为全局。

这是过滤器代码 -

FilterController.cs
:

public IActionResult Index(string postCategory)
{
    var filteredPost = from p in _context.Posts select p;

    if (postCategory != "All")
    {
        if (!string.IsNullOrEmpty(postCategory))
        {
            ViewBag.PostCategory = postCategory;

            filteredPost = filteredPost.Where(p => p.PostCategory == postCategory);
        }
    }
    else if (!string.IsNullOrEmpty("All"))
    {
        filteredPost = _context.Posts;
    }

    return View(await filteredPost.ToListAsync());
}

目前所有控制器都依靠

_context.Posts
来显示数据。该代码根据用户选择的类别过滤
_context.Posts
内的
filteredPost
。我想在其余控制器中使用
filteredPost
而不是
_context.Posts
。我怎样才能实现这个目标?

我想使用

filteredPost
而不是
_context.Posts
的控制器示例:

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

感谢所有建议。谢谢你。

c# asp.net-core-mvc global-filter
1个回答
2
投票

不要将其视为“全局过滤器”——这不是 Web 应用程序框架(好吧)工作的方式。

我不建议使用共享/通用

Controller
子类:从长远来看,这只会导致问题;幸运的是,您所需要的只是一些扩展方法:

public static class MyHttpContextExtensions
{
    /// <summary>Postfix version of <see cref="String.IsNullOrWhiteSpace" />.</summary>
    public static Boolean IsSet( [NotNullWhen(true)] this String? s ) => !String.IsNullOrWhiteSpace( s );

    /// <summary>Case-insensitive ordinal string equality.</summary>
    public static Boolean EqualsIns( this String? left, String? right ) => StringComparer.OrdinalIgnoreCase.Equals( left, right );

    public static async IQueryable<Post> GetFilteredPosts( this HttpContext httpContext )
    {
        if( httpContext is null ) throw new ArgumentNullException(nameof(httpContext));

        MyDbContext dbContext = httpContext.RequestServices.GetRequiredService<MyDbContext>();
        
        String? postCatFilter = httpContext.Request.Query["postCategory"];
        if( postCatFilter.IsSet() && !"all".EqualsIns( postCatFilter ) )
        {
            return dbContext.Posts.Where( p => p.PostCategory == postCatFilter );
        }
        else
        {
            return dbContext.Posts;
        }
    }

    public static async IQueryable<Post> GetFilteredPosts( this ControllerBase controller )
    {
        return GetFilteredPosts( httpContext: controller.HttpContext );
    }
}

那么在你的any

Controller
中,你需要做的就是(例如):

public class ExampleController
{
    private readonly MyDbContext dbContext;

    public ExampleController( MyDbContext dbContext )
    {
        this.dbContext = dbContext ?? throw new ArgumentNullException(nameof(dbContext));
    }

    [Route( "/foo" )]
    public async Task<IActionResult> GetFoo()
    {
        List<Post> postsList = await this.GetFilteredPosts().ToListAsync();
        return this.View( "Foo", postsList );
    }
}

请注意,

MyDbContext
的作用域为每个请求,因此从
MyDbContext
返回的
HttpContext.RequestServices
ExampleController.dbContext
是同一实例。

© www.soinside.com 2019 - 2024. All rights reserved.