如何为ASP.NET Web API按路由单独启用过滤器?
问题解答
一、全局启用过滤器的写法是否正确?
你的写法是正确的。
在HttpSelfHostConfiguration中通过this.Filters.Add(new TestAttribute()),可以将TestAttribute注册为全局过滤器,对所有匹配Web.Controllers命名空间的控制器Action生效。代码顺序不影响功能,但通常建议先配置服务替换,再添加过滤器,最后配置路由,调整后代码如下:
this.Services.Replace(typeof(IHttpControllerTypeResolver), new ControllerTypeResolverByNamespace("Web.Controllers")); this.Filters.Add(new TestAttribute()); this.MapHttpAttributeRoutes();
二、为单个路由启用过滤器的方法
针对你使用的ASP.NET Web API(非Core版本),有以下几种精准匹配特定路由的方案:
1. 直接在目标Action上标记特性
这是最简单直接的方式,将[Test]特性直接加到对应路由的Action方法上:
namespace Web.Controllers { public class TestController { [HttpGet, Route("api/test"), Test] public Boolean Test() { return true; } } }
这种方式完全精准对应api/test路由,无需额外全局配置。
2. 自定义过滤器提供程序匹配路由模板
如果需要批量匹配某类路由(比如多个符合特定模板的路由),可以自定义IFilterProvider实现按路由模板匹配:
public class RouteSpecificFilterProvider : IFilterProvider { public IEnumerable<FilterInfo> GetFilters(HttpConfiguration configuration, HttpActionDescriptor actionDescriptor) { var routeTemplate = actionDescriptor.ActionBinding.RouteData.Route.RouteTemplate; // 匹配目标路由模板 if (routeTemplate.Equals("api/test", StringComparison.OrdinalIgnoreCase)) { yield return new FilterInfo(new TestAttribute(), FilterScope.Action); } } }
然后在配置类中注册该提供程序:
this.Services.Replace(typeof(IHttpControllerTypeResolver), new ControllerTypeResolverByNamespace("Web.Controllers")); // 注册自定义过滤器提供程序 this.Services.Add(typeof(IFilterProvider), new RouteSpecificFilterProvider()); this.MapHttpAttributeRoutes();
3. 控制器级别添加(若控制器仅含目标路由Action)
如果TestController只有Test这一个Action,也可以直接在控制器类上添加特性:
namespace Web.Controllers { [Test] public class TestController { [HttpGet, Route("api/test")] public Boolean Test() { return true; } } }
额外优化提示
你的TestAttribute中OnActionExecuting方法可以简化,因为方法是void类型,无需return赋值语句:
public override void OnActionExecuting(HttpActionContext actionContext) { if (actionContext.RequestContext.ClientCertificate == null) { actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized, "Unauthorized"); return; } base.OnActionExecuting(actionContext); }
内容的提问来源于stack exchange,提问作者greg718
相关产品推荐
相关产品推荐

