ASP.NET Web API:如果从资源设置错误消息,则模型有效
问题是在ApiController中,如果我使用.rsx文件(参考资料)提供自定义错误消息,则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; }
filter:
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.IsValid为false ,响应符合预期:
{ "Message": "The request is invalid.", "ModelState": { "model.Password": [ "The field Password must be a string or array type with a minimum length of '5'." ] } }
但是,如果我在validation属性中使用资源(配置为公共和嵌入式资源构建操作):
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。
资源类是可见的,resharper正确validationErrorMessageResourceName中提供的字符串。
我尝试了你的解决方案,但我不懂类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); } } } }
两个资源文件,一个通用的Resources.resx,包含字符串键/值Test / something; 另一个是Resources.de-DE.resx,包含字符串键/值Test / something_DE。
使用fiddler我发送了这个:
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添加了下一节:
... ...