在ASP.NET Web API中查找无法识别的查询参数

时间:2013-07-24 17:43:07

标签: asp.net asp.net-web-api query-parameters

我在ASP.NET Web API控制器中有一个相当冗长的Get()方法。像这样:

public PaginatedResult Get(int perPage = 10, int pageNum = 0, string param1 = null, [...] string param20 = null)

我想要的是能够处理请求包含不属于方法签名的查询参数的情况。也就是说,如果有人要求:

/?perPage=10&paran19=foo&param21=bar

......我希望能够说,“嘿,那里'paran19'和'param21'都不存在,所以它们不会影响这个查询的结果!”

我能想到的唯一方法就是在Request上调用GetQueryNameValuePairs(),然后使用reflection将该列表与我的Get()方法接受的params进行比较。但这对于这个问题似乎有些过分。有没有更好的办法?理想情况下,一个足够灵活,可以轻松应用于多种方法。

1 个答案:

答案 0 :(得分:0)

所以,希望这个自我答案在SO上并不差,但是从Cj S.的答案中得到一点点刺激,我更多地关注Web API消息生命周期,最后创建了一个Action Filter: / p>

public class QueryParamMatchingActionFilter : ActionFilterAttribute
{

    public override void OnActionExecuting(HttpActionContext filterContext)
    {
        List<string> queryParamNames = filterContext.Request.GetQueryNameValuePairs().Select(q => (string)q.Key.ToLowerInvariant()).ToList();

        List<string> methodParams = filterContext.ActionArguments.Select(q => (string)q.Key.ToLowerInvariant()).ToList();

        List<string> unrecognized = queryParamNames.Where(qp => !methodParams.Any(mp => mp == qp)).ToList();

        if (unrecognized.Count > 0)
        {
            List<string> errors;
            if (filterContext.Request.Properties.ContainsKey("MY_ERRORS"))
                errors = (List<string>)filterContext.Request.Properties["MY_ERRORS"];
            else
                errors = new List<string>();

            foreach (string badParam in unrecognized)
            {
                errors.Add(String.Format("UNRECOGNIZED PARAMETER IGNORED: {0}", badParam));
            }

            filterContext.Request.Properties["MY_ERRORS"] = errors;
        }
    }

}

所以现在我可以用“[QueryParamMatchingActionFilter]”装饰我的控制器。 MY_ERRORS的内容由我已经设置的DelegatingHandler放入响应中,它使用一些有用的元数据包装响应。但是这段代码应该很容易重新用于使用无关的params做其他事情。使用filterContext的ActionArguments属性的能力意味着我们可以跳过使用反射,但如果其他人知道更有效的方法,我仍然不会感到惊讶!