在ASP.net核心中为api和mvc端点分隔过滤器

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

有没有办法分离我的MVC控制器和用于web api目的的过滤器?就像是:

services.AddMvc(options =>
{
     options.Filters.Add(new Filter1()); //MVC           
     options.Filters.Add(new Filter2());//web api only?
});
asp.net asp.net-core
1个回答
0
投票

正如我在评论中所述,在ASP.Net Core中,没有MVC和Web API控制器的分离。所有控制器均源自Microsoft.AspNetCore.Mvc.Controller

它与ASP.NET MVC和Web API完全不同,后者的过滤器和过滤器集合属于两个不同的Universe。

因此,您不能指望ASP.Net Core会根据您的条件为您提供内置的分隔过滤器的方法。 MvcOptions有唯一的Filters系列。

但是,通过使用聚合其他应用程序筛选器的动作筛选器并“知道”它是Web Api还是Mvc操作以及是否应执行底层筛选器,您可以轻松满足您的需求。

这是一个示例:

public class SeparateActionFilter : IActionFilter
{
    private enum FilterType
    {
        Mvc,
        WebApi
    }

    private readonly IActionFilter innerFilter;
    private readonly FilterType filterType;

    public static IActionFilter MvcFilter(IActionFilter innerFilter)
    {
        return new SeparateActionFilter(innerFilter, FilterType.Mvc);
    }

    public static IActionFilter WebApiFilter(IActionFilter innerFilter)
    {
        return new SeparateActionFilter(innerFilter, FilterType.WebApi);
    }

    private SeparateActionFilter(IActionFilter innerFilter, FilterType filterType)
    {
        this.innerFilter = innerFilter ?? throw new ArgumentNullException(nameof(innerFilter));
        this.filterType = filterType;
    }

    public void OnActionExecuting(ActionExecutingContext context)
    {
        if (ShouldExecute(context))
        {
            innerFilter.OnActionExecuting(context);
        }
    }

    public void OnActionExecuted(ActionExecutedContext context)
    {
        if (ShouldExecute(context))
        {
            innerFilter.OnActionExecuted(context);
        }
    }

    private bool ShouldExecute(FilterContext context)
    {
        return filterType == FilterType.Mvc && IsMvcFilter(context) ||
                filterType == FilterType.WebApi && !IsMvcFilter(context);
    }

    private bool IsMvcFilter(FilterContext context)
    {
        //  You logic for separation of MVC and Web Api filters.
        //  You could make checks on context.ActionDescriptor, context.HttpContext or context.RouteData.

        return true;
    }
}

注册过滤器:

services.AddMvc(options =>
{
    options.Filters.Add(SeparateActionFilter.MvcFilter(new Filter1()));    // MVC 
    options.Filters.Add(SeparateActionFilter.WebApiFilter(new Filter2())); //   web api only
});

您只需要在MVC和Web API过滤器之间使用分离逻辑实现IsMvcFilter()方法。在这种方法中,您可以访问FilterContext,其中包含ActionDescriptorHttpContextRouteData等所有必需信息。

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