反序列化HttpError ModelState

时间:2012-08-21 00:49:00

标签: asp.net-web-api

获取我现在拥有的最新webapi位

return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);

我的客户端是一个MVC网站,它从响应中读取值。我终于让它从响应中读取HttpError对象,但是加载ModelState是......至少可以说不直观。

有没有更简洁的方法来写这个?

var httpError = response.Read<HttpError>();
 var errors = httpError["ModelState"] as JObject;

 foreach (var error in errors)
 foreach (var message in error.Value.Values<string>())
 {
     modelState.AddModelError(error.Key, message);
 }

2 个答案:

答案 0 :(得分:3)

虽然您已经确定的错误响应很容易被反序列化为HttpError,但其中的ModelState值最终只能作为JObject。

您可能已尝试过类似的内容:

var errors = ((JObject)errorMsg["ModelState"])
             .ToObject<ModelStateDictionary>();

或者也许:

var errors = ((JObject)errorMsg["ModelState"])
             .ToObject<Dictionary<string, ICollection<ModelError>>>();

并发现它不会转换。我能找到的最佳选择是:

var errors = ((JObject)errorMsg["ModelState"])
             .ToObject<Dictionary<string, IList<string>>>();

这使你的迭代略微更整洁:

foreach (var err in errors)
foreach (var msg in err.Value)
{
    modelStateDictionary.AddModelError(err.Key, msg);
}

正如我所看到的那样,问题是一个字符串不会反序列化为ModelError实例,并且由于错误地隐藏了Collection(IList list)的基类构造函数而被ModelErrorCollection进一步复杂化。

答案 1 :(得分:0)

你是如何进行API调用的?客户端?如果是这样,我注意到Brad Wilson使用以下格式在最近的演示中通过jQuery接收AJAX响应。这可能不是你想要的,但它对我来说效果很好:

$.ajax({
    url: "/apicontorller/action/",
    contentType: "application/json",
    type: "POST",
    data: jsonData,
    statusCode: {
        200: function (data) {

        },
        404: function () {
            alert('404');
        },
        400: function () {
            alert('invalid');
        },
        500: function () {
            alert('error');
        },
        // ...
    }
});

关于这一点的好处是你可以处理实际的HTTP状态代码。根据我的经验,可以通过为谓词函数提供参数来访问错误消息/数据。我还在学习REST和WebAPI平台,所以如果有人能提供更好的实现,我当然欢迎它!