3

問題は、カスタム エラー メッセージを提供するために .rsx ファイル (リソース) を使用する場合、ApiController でModelState.IsValidが常にtrueになることです。

これが私のモデルです:

public class LoginModel
{
    public string Email { get; set; }

    [Required]
    [MinLength(5)]
    public string Password { get; set; }
}

ApiController のメソッド:

    [HttpPost]
    [ModelValidationFilter]
    public void Post(LoginModel model)
    {
        var a = ModelState.IsValid;
    }

そしてフィルター:

public class ModelValidationFilterAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        if (actionContext.ModelState.IsValid == false)
        {
            actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.BadRequest, actionContext.ModelState);
        }
    }
}

これを POST リクエストで送信しています。

{ Email: "asd@asd.com", Password: "a" }

ModelState.IsValidfalseで、応答は期待どおりです。

{
   "Message": "The request is invalid.",
   "ModelState":
   {
       "model.Password":
       [
           "The field Password must be a string or array type with a minimum length of '5'."
       ]
   }
}

しかし、検証属性でリソース ( PublicおよびEmbedded Resourceビルド アクションとして構成) を使用すると、次のようになります。

public class LoginModel
{
    public string Email { get; set; }

    [Required]
    [MinLength(5, ErrorMessageResourceName = "Test", ErrorMessageResourceType = typeof(Resources.Localization))]
    public string Password { get; set; }
}

(' Test ' キーは ' Test ' 文字列値のみを保持します) ModelState.IsValidは true です。

Resources クラスが表示され、 resharper はErrorMessageResourceNameで提供される文字列を正しく検証します。

4

1 に答える 1

3

私はあなたの解決策を試しましたが、Resources.Localization クラスを理解していません。それはどこから来たのか?私の解決策は以下で説明されており、適切なリソースで機能していました。

モデル:

using TestApp.Properties;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;

namespace TestApp.Models
{
    public class LoginModel
    {
        public string Email { get; set; }
        [Required]
        [MinLength(5, ErrorMessageResourceName="Test", ErrorMessageResourceType=typeof(Resources))]
        public string Password { get; set; }
    }
}

ModelValidationFilterAttribute:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Http.Controllers;
using System.Web.Http.Filters;
using System.Net.Http;

namespace TestApp.Controllers
{
    public class ModelValidationFilterAttribute: ActionFilterAttribute
    {
        public override void OnActionExecuting(HttpActionContext actionContext)
        {
            if (actionContext.ModelState.IsValid == false)
            {
                actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.BadRequest, actionContext.ModelState);
            }
        }
    }
}

2 つのリソース ファイル。1 つは一般的な Resources.resx で、文字列キー/値 Test/something を含みます。もう 1 つの Resources.de-DE.resx には、文字列キー/値 Test/something_DE が含まれています。

フィドラーを使用して、これを送信しました:

Header:
User-Agent: Fiddler
Host: localhost:63315
Content-Length: 37
Content-Type: application/json

体:

{Email:"text@test.com", Password:"a"}

応答は文字列でした:

HTTP/1.1 400 Bad Request
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/json; charset=utf-8
Expires: -1
Server: Microsoft-IIS/8.0
X-AspNet-Version: 4.0.30319
X-SourceFiles: =?UTF-8?B?RDpcV29ya1xDU1xGYkJpcnRoZGF5QXBwXEZiQmRheUFwcDJcYXBpXGxvZ2lu?=
X-Powered-By: ASP.NET
Date: Fri, 28 Jun 2013 14:56:54 GMT
Content-Length: 83

{"Message":"The request is invalid.","ModelState":{"model.Password":["something"]}}

de-DE の場合、リクエスト ヘッダーは次のとおりです。

User-Agent: Fiddler
Host: localhost:63315
Content-Length: 37
Accept-Language: de-DE
Content-Type: application/json

応答は次のとおりです。

HTTP/1.1 400 Bad Request
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/json; charset=utf-8
Expires: -1
Server: Microsoft-IIS/8.0
X-AspNet-Version: 4.0.30319
X-SourceFiles: =?UTF-8?B?RDpcV29ya1xDU1xGYkJpcnRoZGF5QXBwXEZiQmRheUFwcDJcYXBpXGxvZ2lu?=
X-Powered-By: ASP.NET
Date: Fri, 28 Jun 2013 14:57:39 GMT
Content-Length: 86

{"Message":"The request is invalid.","ModelState":{"model.Password":["something_DE"]}}

ご覧のとおり、メッセージはローカライズされたリソース ファイルから読み取られたため、"_DE" でした。

これはあなたが達成したかったことですか?

敬具。

編集:ルート構成は

config.Routes.MapHttpRoute(
          name: "LoginRoute",
          routeTemplate: "api/login",
          defaults: new { controller = "Login", action = "PostLogin" },
          constraints: new { httpMethod = new HttpMethodConstraint(HttpMethod.Post) }
          );

Web.config に次のセクションが追加されました。

<system.web>
...
        <globalization culture="auto" uiCulture="auto" />
...
</system.web>
于 2013-06-28T15:00:00.307 に答える