能否在Action Filter中修改Web API的FromUri参数?
解决Web API参数预处理重复问题:用Action Filter提前统一处理DateTime参数
我之前遇到过一模一样的情况——Web API里多个接口都要接收带dateFrom和dateTo的参数对象,每次都在接口入口写重复的预处理代码,既麻烦又容易出错。后来用Action Filter完美解决了这个问题,把预处理逻辑统一抽出来,在参数进入接口前就处理好,给你分享完整的实现方案:
完整的Action Filter实现步骤
1. 编写MyActionParamFilter过滤器
这个过滤器会在Action执行前(OnActionExecuting阶段)自动遍历所有参数,找到包含dateFrom和dateTo的对象并执行预处理逻辑(下面的例子是补全天的起止时间,你可以根据自己的需求修改):
using System; using System.Reflection; using System.Web.Http.Controllers; using System.Web.Http.Filters; public class MyActionParamFilter : ActionFilterAttribute { public override void OnActionExecuting(HttpActionContext actionContext) { // 遍历所有Action参数,寻找目标参数对象 foreach (var parameter in actionContext.ActionArguments.Values) { if (parameter == null) continue; var paramType = parameter.GetType(); // 获取dateFrom和dateTo的属性(如果是字段就用GetField) var dateFromProp = paramType.GetProperty("dateFrom", BindingFlags.Public | BindingFlags.Instance); var dateToProp = paramType.GetProperty("dateTo", BindingFlags.Public | BindingFlags.Instance); // 处理dateFrom:比如转为当天起始时间 if (dateFromProp != null && dateFromProp.PropertyType == typeof(DateTime)) { var originalDate = (DateTime)dateFromProp.GetValue(parameter); var processedDate = originalDate.Date; // 00:00:00 dateFromProp.SetValue(parameter, processedDate); } // 处理dateTo:比如转为当天结束时间 if (dateToProp != null && dateToProp.PropertyType == typeof(DateTime)) { var originalDate = (DateTime)dateToProp.GetValue(parameter); var processedDate = originalDate.Date.AddDays(1).AddMilliseconds(-1); // 23:59:59.999 dateToProp.SetValue(parameter, processedDate); } } base.OnActionExecuting(actionContext); } }
2. 注册过滤器
有两种注册方式,按需选择:
方式一:全局注册(所有API接口自动生效)
在WebApiConfig.cs的Register方法里添加过滤器注册:
public static void Register(HttpConfiguration config) { // 添加全局Action过滤器 config.Filters.Add(new MyActionParamFilter()); // 其他API配置路由、格式化等代码... }
方式二:局部注册(仅指定Controller/Action生效)
直接在目标Controller或Action上标记特性即可:
// 对整个Controller下的所有接口生效 [MyActionParamFilter] public class OrdersController : ApiController { public IHttpActionResult GetOrders([FromUri] DateRangeParam param) { // 这里的param已经被预处理过,直接用就行 return Ok(); } } // 或者只给单个接口加过滤器 public class ProductsController : ApiController { [MyActionParamFilter] public IHttpActionResult GetProducts([FromBody] DateRangeParam param) { // 预处理后的参数直接使用 return Ok(); } }
3. 额外提示
- 不管参数是
[FromUri]还是[FromBody]传递的,这个过滤器都能正常工作,因为ActionArguments里已经是解析好的参数对象。 - 你可以根据实际需求修改预处理逻辑,比如统一转UTC时间、校验
dateFrom不能晚于dateTo、默认补全日期等。 - 只要参数类包含
dateFrom和dateTo这两个DateTime类型的属性,过滤器就会自动处理,不用为每个参数类单独写逻辑。
内容的提问来源于stack exchange,提问作者zeroflaw
相关产品推荐
相关产品推荐

