Using ModelState to return errors from WebAPI 2

I am trying to use the ModelState object to send Errors to the client; I am using asp.net API for a service.

On the web service side, I do this.

public HttpResponseMessage VerifyData(Cobject data) { string[] errors; if (!VerifyAllRequiredData(data, out errors)) { foreach(string error in errors) ModelState.AddModelError("", error); return Request.CreateErrorResponse(HttpStatusCode.ExpectationFailed, ModelState); } return Request.CreateResponse(HttpStatusCode.OK, data); } 

I am creating a .NET Client library for this service, so we can use it for exsiting Windows applications.

on the client side:

  public bool VerifyData(Cobject data) { try { HttpClient c = new HttpClient(); c.BaseAddress = BaseAddress; c.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(JsonHeader)); c.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(HTMLHeader)); c.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(TextHeader)); var asyncResponse = this.PostAsJsonAsync(url, data); asyncResponse.Wait(); asyncResponse.Result.EnsureSuccessStatusCode(); return true; } catch (HttpRequestException hre) { Console.WriteLine(hre.Message); return false; } catch (Exception e) { Console.WriteLine(e.Message); return false; } } 

The problem here is that I do not see the messages that were added to the ModelState on the repository. I see the status (ExpectionFailed), but no messages. How to receive these messages on the client?

+6
source share
3 answers

I use "similar" code to create messages and access my web api. Let me copy the code so you can get the information from ModelState

 var responseTask = await client.SendAsync(request); var result = responseTask.ContinueWith(async r => { var response = r.Result; var value = await response.Content.ReadAsStringAsync(); if (!response.IsSuccessStatusCode) { var obj = new { message = "", ModelState = new Dictionary<string,string[]>() }; var x = JsonConvert.DeserializeAnonymousType(value, obj); throw new AggregateException(x.ModelState.Select(kvp => new Exception(string.Format("{0}: {1}", kvp.Key, string.Join(". ", kvp.Value))))); } }).Result; 

I hope this is the trick for you :)

+11
source

I created a strong typed object and used as shown below:

 public class BadRequestResponse { public string Message { get; set; } public Dictionary<string, string[]> ModelState { get; set; } } 

and used it to deserialize JSON, as in this example:

  public async Task DoStuff() { using (var client = new HttpClient()) { client.BaseAddress = "http://localhost/"; client.DefaultRequestHeaders.Accept.Clear(); client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); RegisterUserRequest content = new RegisterUserRequest { ConfirmPassword = "foo", Password = "foo", Email = " foo@bar " }; HttpResponseMessage response = await client.PostAsJsonAsync("api/Account/Register", content).ConfigureAwait(false); if (response.StatusCode == System.Net.HttpStatusCode.BadRequest) { BadRequestResponse message = await response.Content.ReadAsAsync<BadRequestResponse>().ConfigureAwait(false); // do something with "message.ModelState.Values" } } } 

You can check HttpStatusCode.ExpectationFailed instead of HttpStatusCode.BadRequest .

I also installed the WebApi Client package (since this ReadAsAsync overload is an extension from this library):

 Install-Package Microsoft.AspNet.WebApi.Client 
+8
source

In fact, you can solve the problem using "CreateErrorResponse". This method has an overload that gives you the option to send ModelState back

  [HttpGet] public HttpResponseMessage Get([FromUri]InputFilterModel filter) { try { if (filter == null || ModelState.IsValid == false) { return (filter == null)? Request.CreateErrorResponse(HttpStatusCode.BadRequest,"Input parameter can not be null") : Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState); } 

The state of the model returns Json with each field in the model with a validation problem. You can see that it executes the request directly in the browser or with the help of a violinist.

0
source

All Articles