从System.Net.WebRequest获取完整的响应体

13

我正在使用System.Net.WebRequest从某些API获取信息。当我遇到错误时,响应仅包含基本的HttpStatusCode和消息,而不是完整的错误返回值。相比之下,如果在像POSTMAN这样的工具中运行相同的POST数据和标头,则会从该API返回完整的错误。

我想知道是否有某种属性或方法可以获取完整的错误响应?

以下是我正在运行的代码:

public HttpStatusCode GetRestResponse(
    string verb,
    string requestUrl,
    string userName,
    string password,
    out string receiveContent,
    string postContent = null)
{
    var request = (HttpWebRequest)WebRequest.Create(requestUrl);
    request.Method = verb;

    if (!string.IsNullOrEmpty(userName))
    {
        string authInfo = string.Format("{0}:{1}", userName, password);
        authInfo = Convert.ToBase64String(Encoding.Default.GetBytes(authInfo));
        request.Headers.Add("Authorization", "Basic " + authInfo);
    }

    if (!string.IsNullOrEmpty(postContent))
    {
        byte[] byteArray = Encoding.UTF8.GetBytes(postContent);
        request.ContentType = "application/json; charset=utf-8";
        request.ContentLength = byteArray.Length;
        var dataStream = request.GetRequestStream();
        dataStream.Write(byteArray, 0, byteArray.Length);
        dataStream.Close();
    }

    try
    {
        using (WebResponse response = request.GetResponse())
        {
            var responseStream = response.GetResponseStream();
            if (responseStream != null)
            {
                var reader = new StreamReader(responseStream);
                receiveContent = reader.ReadToEnd();
                reader.Close();

                return ((HttpWebResponse) response).StatusCode;
            }
        }
    }
    catch (Exception ex)
    {
        receiveContent = string.Format("{0}\n{1}\nposted content = \n{2}", ex, ex.Message, postContent);
        return HttpStatusCode.BadRequest;
    }

    receiveContent = null;
    return 0;
}

当我发出一个请求出现错误时,错误消息会显示:The remote server returned an error: (400) Bad Request.没有InnerException,也没有其他任何有用的异常信息。

[回答] @Rene指出了正确的方向,可以通过以下方式获取适当的响应正文:

var reader = new StreamReader(ex.Response.GetResponseStream());
var content = reader.ReadToEnd();
1个回答

12
您正在捕获通用异常,因此没有太多特定信息的空间。
您应该捕获由几个Web请求类抛出的专用异常,即WebException
您的catch代码可以像这样:
catch (WebException e)
{
    var response = ((HttpWebResponse)e.Response);
    var someheader = response.Headers["X-API-ERROR"];
    // check header

    if (e.Status == WebExceptionStatus.ProtocolError)
    {
        // protocol errors find the statuscode in the Response
        // the enum statuscode can be cast to an int.
        int code = (int) ((HttpWebResponse)e.Response).StatusCode;
        string content;
        using(var reader = new StreamReader(e.Response.GetResponseStream()))
        {
            content = reader.ReadToEnd();
        }
        // do what ever you want to store and return to your callers
    }
}

WebException 实例中,您还可以访问从主机发送的 Response,因此您可以访问发送给您的任何内容。


这实际上是在我开始干涉它之前的陷阱。我仍然不知道如何以那种方式获得特定于API的响应。我已经搜索了对象并再次搜索,但找不到任何相关的内容。 - AlexD
我已经添加了如何检查其他内容的方法。也许你可以分享一下Postman显示的内容,这样我就能理解你想要什么了。 - rene
这是我在POSTMAN中获得的响应:http://pastebin.com/uDRDesd7这是头文件集合:http://pastebin.com/FVzd7kWS - AlexD
实际上,我尝试使用以下方式读取ConnectStream: new StreamReader(((((HttpWebResponse)ex.Response))).m_ConnectStream).ReadToEnd(),似乎可以解决问题。我马上会更新。 - AlexD
2
var reader = new StreamReader(ex.Response.GetResponseStream()); var content = reader.ReadToEnd(); 运行良好 :) 谢谢! - AlexD

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接