5

WebAPIのグローバル検証属性を作成したかったのです。だから私はチュートリアルに従い、次の属性になりました:

public class ValidationActionFilter : ActionFilterAttribute
{
    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        if (actionContext.ModelState.IsValid)
        {
            return;
        }

        var errors = new List<KeyValuePair<string, string>>();
        foreach (var key in actionContext.ModelState.Keys.Where(key =>
            actionContext.ModelState[key].Errors.Any()))
        {
            errors.AddRange(actionContext.ModelState[key].Errors
                  .Select(er => new KeyValuePair<string, string>(key, er.ErrorMessage)));
        }

        actionContext.Response =
            actionContext.Request.CreateResponse(HttpStatusCode.BadRequest, errors);
    }
}

次に、Global.asaxのグローバルフィトラーに追加しました。

configuration.Filters.Add(new ValidationActionFilter());

ほとんどのアクションでうまく機能しますが、オプションでnull許容のリクエストパラメーターを持つアクションでは期待どおりには機能しません。

例えば:

ルートを作成しました:

routes.MapHttpRoute(
    name: "Optional parameters route", 
    routeTemplate: "api/{controller}", 
    defaults: new { skip = UrlParameter.Optional, take = UrlParameter.Optional });

そして私の中での行動ProductsController

public HttpResponseMessage GetAllProducts(int? skip, int? take)
{
    var products = this._productService.GetProducts(skip, take, MaxTake);

    return this.Request.CreateResponse(HttpStatusCode.OK, this._backwardMapper.Map(products));
}

このURLをリクエストするhttp://locahost/api/productsと、403ステータスコードと次のコンテンツを含む応答が返されます。

[
{
    "Key": "skip.Nullable`1",
    "Value": "A value is required but was not present in the request."
},
{
    "Key": "take.Nullable`1",
    "Value": "A value is required but was not present in the request."
}
]

これらのパラメーターはオプションであり、null許容であるため、これは検証エラーとして表示されるべきではないと思います。

誰かがこの問題に遭遇し、解決策を見つけましたか?

4

2 に答える 2

4

GETリクエストのプリミティブ型のモデル検証を回避/抑制したい場合もあります。

public class ModelValidationFilter : ActionFilterAttribute
    {
        public override void OnActionExecuting(HttpActionContext actionContext)
        {
            if (!actionContext.ModelState.IsValid && actionContext.Request.Method != HttpMethod.Get)
            { ...
于 2013-02-12T09:58:43.630 に答える
2

Web APIとMVCの間でコードをめちゃくちゃにしたようですが、MVCのUrlParameterではなく、WebAPIのRouteParameterを使用する必要あります

routes.MapHttpRoute(
    name: "Optional parameters route", 
    routeTemplate: "api/{controller}", 
    defaults: new { skip = RouteParameter.Optional, take = RouteParameter.Optional }
    );

だが:

ルートスキップアンドテイクのデフォルトパラメータは、ルートテンプレートではなくクエリ文字列で使用するだけなので、ルートメカニズムには何の役割も果たしません。したがって、最も修正的なルートは次のようになります。

routes.MapHttpRoute(
    name: "Optional parameters route", 
    routeTemplate: "api/{controller}"
    );
于 2012-08-10T16:52:32.180 に答える