问题
TL;DR;
"I like how my generated AutoRest client deserializes my main entities when dealing with the 200 scenarios.. but, MUST I manually parse the 400 scenarios?", said the lazy programmer
DETAILS:
So, I have an API, (Web API 2), and I do all the standard stuff.. using POCO's that implement IValidatable
in addition to property-level validation using System.Data.DataAnnotations
my Web API returns 400 errors like this (just an example):
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
And, where appropriate I use SwaggerResponse
attributes, and my swagger.json is documented thus so that my generated client knows that a 400 is a viable response.
Now, my unit tests which directly instantiate the api controllers, I purposely try to test for invalid model state.. I can take the IHttpActionResult
response from the controller invocation, and cast it to InvalidModelStateResult
and iterate over the ModelState dictionary.
But, I find writing something similar for my 'production HTTP calls' with an actual HTTP client -- not as straightforward.
So, getting closer to the heart of my question:
Is there a preferred method for deserializing the InvalidModelStateResult
?
So, when interacting with my API with actual http calls.. via the Microsoft.Rest.ServiceClient
the JSON that I get back is in a slightly different shape..
Example MVC controller code interacting with my API:
HttpOperationResponse resp = await client.SpecialLocations.PatchByIdWithHttpMessagesAsync(id, locationType, "return=representation");
if (!resp.Response.IsSuccessStatusCode)
{
//The JSON returned here is not really in the form of an InvalidModelStateResult
ViewBag.Error = await resp.Response.Content.ReadAsStringAsync();
return View(locationType);
}
回答1:
So, for now, I'm using Newtonsoft's JObject
to parse ModelState
returned from my WebAPI (again - it's not really named as such once retrieved via http request) and now pushing it into my MVC controller's ModelState
.
This is my answer for now. But will consider others that have any merit. It just seems like a weird thing to have to do.
HttpOperationResponse resp = await client.SpecialLocations.PatchByIdWithHttpMessagesAsync(id, locationType, "return=representation");
if (resp.Response.StatusCode == HttpStatusCode.BadRequest)
{
string jsonErrStr = await resp.Response.Content.ReadAsStringAsync();
JObject err = JObject.Parse(jsonErrStr);
string[] valPair = ((string)err["error"]["innererror"]["message"]).Split(":".ToCharArray());
//now push into MVC controller's modelstate, so jQuery validation can show it
this.ModelState.AddModelError(valPair[0].Trim(),valPair[1].Trim());
return View(locationType);
}
来源:https://stackoverflow.com/questions/50274989/should-i-try-to-take-badrequestmodelstate-returned-from-my-api-and-deserializ