Reputation: 7591
Wit the latest webapi bits I now have
return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);
My client is an MVC website that reads the value from the response. I finally got it to read the HttpError object from the response, but loading the ModelState is... not intuitive to say the least.
Is there a cleaner way to write this?
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);
}
Upvotes: 4
Views: 3714
Reputation: 4297
While an error response, as you've identified, can readily be deserialised into an HttpError, the ModelState value within it only ends up as a JObject.
You've probably already tried something like:
var errors = ((JObject)errorMsg["ModelState"])
.ToObject<ModelStateDictionary>();
Or maybe:
var errors = ((JObject)errorMsg["ModelState"])
.ToObject<Dictionary<string, ICollection<ModelError>>>();
And found that it won't convert. The best alternative I could find was:
var errors = ((JObject)errorMsg["ModelState"])
.ToObject<Dictionary<string, IList<string>>>();
Which makes your iteration marginally neater:
foreach (var err in errors)
foreach (var msg in err.Value)
{
modelStateDictionary.AddModelError(err.Key, msg);
}
The problem, as I see it, is a string won't deserialise to a ModelError instance, and is further compounded by ModelErrorCollection unfortunately hiding its base class constructor of Collection(IList list)
.
Upvotes: 3
Reputation: 5095
How are you making the API calls? Client-side? If so, I noticed Brad Wilson using the below format for receiving AJAX responses via jQuery in a recent demo. This may not be what you're looking for but it's been working well for me:
$.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');
},
// ...
}
});
The nice thing about this is you can handle the actual HTTP status codes. In my experience, error messages/data can be accessed by providing a parameter to the predicate function. I'm still learning about REST and the WebAPI platform so if anyone can provide a better implementation, I certainly welcome it!
Upvotes: 0