1

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』も存在しないので、このクエリの結果には影響しません!」と言えるようになりたいです。

これを処理するために私が考えることができる唯一の方法は、リクエストで GetQueryNameValuePairs() を呼び出し、次にリフレクションを使用して、そのリストを Get() メソッドによって受け入れられたパラメーターと比較することです。しかし、それはこの問題にとってやり過ぎのようです。より良い方法はありますか?理想的には、複数のメソッドに簡単に適用できるほど柔軟な 1 つです。

4

1 に答える 1

0

ですから、この自己回答が SO の悪い形ではないことを願っていますが、Cj S. の回答を少し参考にして、Web API メッセージのライフサイクルを詳しく調べ、最終的にアクション フィルターを作成しました。

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 によって応答に入れられます。これは、いくつかの有用なメタデータで応答をラップします。しかし、このコードは、無関係なパラメーターを使用して他のことを行うために再利用するのに十分簡単なはずです。filterContext の ActionArguments プロパティを使用できるということは、リフレクションの使用をスキップできることを意味します。

于 2013-07-24T22:43:45.197 に答える