Should I try to take BadRequest(ModelState) returned from my API, and deserialize to *what* with JSON.NET?

假如想象 提交于 2019-12-24 20:25:20

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!