Question

I created some web apis and when an error happens the api returns HttpResponseMessage that is created with CreateErrorResponse message. Something like this:

return Request.CreateErrorResponse(
              HttpStatusCode.NotFound, "Failed to find customer.");

My problem is that I cannot figure out how to retrieve the message (in this case "Failed to find customer.") in consumer application.

Here's a sample of the consumer:

private static void GetCustomer()
{
    var client = new HttpClient();
    client.DefaultRequestHeaders.Accept.Add(
                new MediaTypeWithQualityHeaderValue("application/json"));
    string data =
        "{\"LastName\": \"Test\", \"FirstName\": \"Test\"";

    var content = new StringContent(data, Encoding.UTF8, "application/json");

    var httpResponseMessage = 
                 client.PostAsync(
                    new Uri("http://localhost:55202/api/Customer/Find"),
                    content).Result;
    if (httpResponseMessage.IsSuccessStatusCode)
    {
        var cust = httpResponseMessage.Content.
                  ReadAsAsync<IEnumerable<CustomerMobil>>().Result;
    }
}

Any help is greatly appreciated.

Was it helpful?

Solution

Make sure you set the accept and or content type appropriately (possible source of 500 errors on parsing the request content):

client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

content.Headers.ContentType = new MediaTypeWithQualityHeaderValue("application/json");

Then you could just do:

var errorMessage = response.Content.ReadAsStringAsync().Result;

That's all on the client of course. WebApi should handle the formatting of the content appropriately based on the accept and/or content type. Curious, you might also be able to throw new HttpResponseException("Failed to find customer.", HttpStatusCode.NotFound);

OTHER TIPS

One way to get the message is to do:

((ObjectContent)httpResponseMessage.Content).Value

This will give you a dictionary that contains also the Message.

UPDATE

Refer to the official page:

http://msdn.microsoft.com/en-us/library/jj127065(v=vs.108).aspx

You have to vary the way you're reading the successful response and the error response as one is obviously in your case StreamContent, and the other should be ObjectContent.

UPDATE 2

Have you tried doing it this way ?

if (httpResponseMessage.IsSuccessStatusCode)
    {
        var cust = httpResponseMessage.Content.
                  ReadAsAsync<IEnumerable<CustomerMobil>>().Result;
    }
else
{
   var content = httpResponseMessage.Content as ObjectContent;

   if (content != null)
    {
       // do something with the content
       var error = content.Value;
    }
   else
   {
      Console.WriteLine("content was of type ", (httpResponseMessage.Content).GetType());
   }

}

FINAL UPDATE (hopefully...)

OK, now I understand it - just try doing this instead:

httpResponseMessage.Content.ReadAsAsync<HttpError>().Result;

This is an option to get the message from the error response that avoids making an ...Async().Result() type of call.

((HttpError)((ObjectContent<HttpError>)response.Content).Value).Message

You should make sure that response.Content is of type ObjectContent<HttpError> first though.

It should be in HttpResponseMessage.ReasonPhrase. If that sounds like a bit of a strange name, it's just because that is the way it is named in the HTTP specification http://www.w3.org/Protocols/rfc2616/rfc2616-sec6.html

OK this is hilarious, but using QuickWatch I came up with this elegant solution:

(new System.Collections.Generic.Mscorlib_DictionaryDebugView(((System.Web.Http.HttpError)(((System.Net.Http.ObjectContent)(httpResponseMessage.Content)).Value)))).Items[0].Value

That is super readable!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top