asp.net-web-api – Web API / JsonMediaTypeFormatter接受无效
我有以下型号:
public class Resource { [DataMember(IsRequired = true)] [Required] public bool IsPublic { get; set; } [DataMember(IsRequired = true)] [Required] public ResourceKey ResourceKey { get; set; } } public class ResourceKey { [StringLength(50,MinimumLength = 1)] [Required] public string SystemId { get; set; } [StringLength(50,MinimumLength = 1)] [Required] public string SystemDataIdType { get; set; } [StringLength(50,MinimumLength = 1)] [Required] public string SystemEntityType { get; set; } [StringLength(50,MinimumLength = 1)] [Required] public string SystemDataId { get; set; } } 我有以下操作方法签名: public HttpResponseMessage PostResource(Resource resource) 我在正文中发送了以下带有JSON的请求(属性“IsPublic”的故意无效值): Request Method:POST Host: localhost:63307 Connection: keep-alive Content-Length: 477 User-Agent: Mozilla/5.0 (Windows NT 6.0) AppleWebKit/537.22 (KHTML,like Gecko) Chrome/25.0.1364.97 Safari/537.22 Origin: chrome-extension://hgmloofddffdnphfgcellkdfbfbjeloo Content-Type: application/json Accept: */* Accept-Encoding: gzip,deflate,sdch Accept-Language: en-US,en;q=0.8 Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3 { "IsPublic": invalidvalue,"ResourceKey":{ "SystemId": "asdf","SystemDataIdType": "int","SystemDataId": "Lorem ipsum","SystemEntityType":"EntityType" },} 这是无效的JSON – 通过JSONLint运行它并告诉您:
ModelState.IsValid属性为’true’ – 为什么??? 此外,格式化程序似乎放弃了反序列化,而只是将’resource’参数传递给action方法,而不是抛出验证错误! 请注意,如果我为其他属性添加了无效值,例如,也会发生这种情况.代: "SystemId": notAnObjectOrLiteralOrArray 但是,如果我发送以下JSON与“SystemId”属性的特殊未定义值: { "IsPublic": true,ResourceKey:{ "SystemId": undefined,} 然后我得到以下,合理的,异常抛出: Exception Type: Newtonsoft.Json.JsonReaderException Message: "Error reading string. Unexpected token: Undefined. Path 'ResourceKey.SystemId',line 4,position 24." Stack Trace: " at Newtonsoft.Json.JsonReader.ReadAsStringInternal() at Newtonsoft.Json.JsonTextReader.ReadAsString() at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.ReadForType(JsonReader reader,JsonContract contract,Boolean hasConverter) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Object newObject,JsonReader reader,JsonObjectContract contract,JsonProperty member,String id)" 那么:在Newtonsoft.Json库中发生了什么导致看起来像是部分JSON验证??? PS:可以将JSON名称/值对发布到Web API,而无需将名称括在引号中… { IsPublic: true,ResourceKey:{ SystemId: "123",SystemDataIdType: "int",SystemDataId: "Lorem ipsum",SystemEntityType:"EntityType" },} 这也是无效的JSON! 解决方法
好的 – 所以看来部分问题是由我自己造成的.
我在控制器上有两个过滤器: >检查是否有任何空操作参数传递给操作方法,如果是,则返回“400 Bad Request”响应,规定参数不能为null. 我犯的错误是在模型状态检查过滤器之前放置null参数过滤器. 在模型绑定之后,序列化将在第一个JSON示例中正确失败,并且会将相关的序列化异常放在ModelState中,并且action参数将保持为null,这是正确的. 但是,由于第一个过滤器检查空参数然后返回“404错误请求”响应,因此ModelState过滤器从未启动… 因此,似乎验证没有发生,事实上确实如此,但结果却被忽略了! 重要说明:模型绑定期间发生的序列化异常放在ModelState KeyValue对的“异常”属性中…不在ErrorMessage属性中! 为了帮助其他人进行这种区分,这里是我的ModelValidationFilterAttribute: public class ModelValidationFilterAttribute : ActionFilterAttribute { public override void OnActionExecuting(HttpActionContext actionContext) { if (actionContext.ModelState.IsValid) return; // Return the validation errors in the response body. var errors = new Dictionary<string,IEnumerable<string>>(); foreach (KeyValuePair<string,ModelState> keyValue in actionContext.ModelState) { var modelErrors = keyValue.Value.Errors.Where(e => e.ErrorMessage != string.Empty).Select(e => e.ErrorMessage).ToList(); if (modelErrors.Count > 0) errors[keyValue.Key] = modelErrors; // Add details of any Serialization exceptions as well var modelExceptions = keyValue.Value.Errors.Where(e => e.Exception != null).Select(e => e.Exception.Message).ToList(); if (modelExceptions.Count > 0) errors[keyValue.Key + "_exception"] = modelExceptions; } actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.BadRequest,errors); } } 这是动作方法,过滤器的顺序正确: [ModelValidationFilter] [ActionArgNotNullFilter] public HttpResponseMessage PostResource(Resource resource) 现在,以下JSON结果如下: { "IsPublic": invalidvalue,} { "resource.IsPublic_exception": [(2) "Unexpected character encountered while parsing value: i. Path 'IsPublic',line 2,position 21.","Unexpected character encountered while parsing value: i. Path 'IsPublic',position 21." ]- } 但是,所有这些都无法解释为什么JSONMediaTypeFormatter仍然会解析无效JSON,例如它不要求名称是字符串. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- asp.net-mvc-4 – 当连接connecttring configSource时,Visu
- asp.net-mvc-3 – 向@ Html.ValidationSummary添加错误消息
- 指定ASP.NET Http Handler的确切路径
- asp.net-mvc – MVC与WebForms
- asp.net – 如何将HTML页面转换为.ASPX页面并向其添加/删除
- asp.net-core – 如何在ASP.NET Core中实现angular 4 serve
- 将空白字段值传递给存储过程ASP .NET C#
- 关于Type Initializer和 BeforeFieldInit的问题,看看大家能
- asp.net – @RenderSection在嵌套剃刀模板
- asp.net-mvc-4 – MVC 4 Razor如果拆分div标签