【问题标题】:How to retrieve message from WEB API?如何从 WEB API 检索消息?
【发布时间】:2013-01-11 21:53:05
【问题描述】:

我创建了一些 Web api,当发生错误时,api 返回使用 CreateErrorResponse 消息创建的 HttpResponseMessage。像这样的:

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

我的问题是我无法弄清楚如何在消费者应用程序中检索消息(在本例中为“未能找到客户。”)。

这是消费者的样本:

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;
    }
}

非常感谢任何帮助。

【问题讨论】:

  • 你能把代码贴在你真正试图阅读错误信息的地方吗?在这种情况下,消息的内容实际上应该是带有 HttpError 对象的 ObjectContent - 请参阅官方页面:msdn.microsoft.com/en-us/library/jj127065(v=vs.108).aspx 无论哪种方式,您都必须改变读取成功响应和错误响应的方式,因为一个显然是在你的情况下是 StreamContent,另一个应该是 ObjectContent
  • @JoannaTurban - 这是代码。我不知道如何阅读错误消息,这就是我发布问题的原因。到目前为止,您一直是最有帮助的人,但我仍然没有解决我的问题。我正在按照您的链接尝试更多的事情。我走神了,没有解决这个问题。但现在我又想弄清楚了。
  • 你可以试试下面Update2中的代码,看看如果出现错误你仍然得到StreamContent吗?
  • 我假设您想查看内容的类型。这是输出。 “内容的类型是 System.Net.Http.StreamContent。”我必须添加 {0} 才能输出类型。
  • 好的,那么另一个问题 - 你什么时候创建错误响应?在什么条件下?是否只是在例外情况下?请注意,仅当状态代码在 200-299 内时,IsSuccessfulStatusCode 才会计算为 true。是不是对于一个特定的状态代码,比如 400,你会期待一条错误消息,但实际上它从来没有通过正在创建的方法/过滤器?也许添加一些日志来查看是否已经调用了 createErrorResponse 方法

标签: asp.net-web-api consumer


【解决方案1】:

获取消息的一种方法是:

((ObjectContent)httpResponseMessage.Content).Value

这将为您提供一个包含Message 的字典。

更新

参考官方页面:

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

您必须改变读取成功响应和错误响应的方式,因为其中一个显然是 StreamContent,另一个应该是 ObjectContent。

更新 2

你试过这样做吗?

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());
   }

}

最终更新(希望...)

好的,现在我明白了 - 请尝试这样做:

httpResponseMessage.Content.ReadAsAsync&lt;HttpError&gt;().Result;

【讨论】:

  • 不幸的是,当我尝试这个时,我得到了 InvalidCastException。 Message=无法将“System.Net.Http.StreamContent”类型的对象转换为“System.Net.Http.ObjectContent”类型。
  • @Vadim - 尝试读取流然后((StreamContent)httpResponseMessage.Content).ReadAsAsync&lt;string&gt;().Result(或您期望的任何类型 - 尝试对象并查看结果可能)
  • 这正是我正在做的检索数据,它工作正常。但我想检索错误信息。
  • 乔安娜就在这里。如果要返回 CreateErrorResponse 的值,则响应消息内容应该是 ObjectContent。如果它实际上是 StreamContent,那么您将返回其他内容。
【解决方案2】:

它应该在 HttpResponseMessage.ReasonPhrase 中。如果这听起来有点奇怪,那只是因为它在 HTTP 规范中是这样命名的 http://www.w3.org/Protocols/rfc2616/rfc2616-sec6.html

【讨论】:

  • ReasonPhrase 以 statusCode 的形式返回,所以如果是 500,我会收到“InternalServerError”
  • @JoannaTurban 哦,太糟糕了。我希望 CreateErrorResponse 会设置 ReasonPhrase。好吧,您可以在服务器上手动设置 ReasonPhrase,也可以在客户端反序列化 JSON/XML 正文。
【解决方案3】:

确保您正确设置了接受和/或内容类型(解析请求内容时出现 500 错误的可能来源):

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

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

那么你可以这样做:

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

当然,这一切都在客户端。 WebApi 应该根据接受和/或内容类型适当地处理内容的格式。好奇的你也可以throw new HttpResponseException("Failed to find customer.", HttpStatusCode.NotFound);

【讨论】:

  • var errorMessage = response.Content.ReadAsStringAsync().Result;这正是我所缺少的。
  • 这会产生整个结构,而不仅仅是结果(需要 System.Web.Http 程序集):httpResponseMessage.Content.ReadAsAsync()
【解决方案4】:

好的,这很有趣,但是使用 QuickWatch 我想出了这个优雅的解决方案:

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

可读性极强!

【讨论】:

    【解决方案5】:

    这是一个从错误响应中获取消息的选项,可避免进行...Async().Result() 类型的调用。

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

    您应该首先确保response.Content 的类型为ObjectContent&lt;HttpError&gt;

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-05
      • 2019-11-21
      • 2023-03-26
      • 2015-07-10
      • 1970-01-01
      • 2018-03-30
      • 2018-11-23
      • 1970-01-01
      相关资源
      最近更新 更多