【问题标题】:Read text from response从响应中读取文本
【发布时间】:2011-03-17 10:29:13
【问题描述】:
HttpWebRequest request = WebRequest.Create("http://google.com") as HttpWebRequest;  

request.Accept = "application/xrds+xml";  
HttpWebResponse response = (HttpWebResponse)request.GetResponse();  

WebHeaderCollection header = response.Headers;

这里谷歌返回文本。怎么读?

【问题讨论】:

    标签: c# asp.net


    【解决方案1】:

    您的 "application/xrds+xml" 给了我问题,我收到的 Content-Length 为 0(无响应)。

    删除后,您可以使用response.GetResponseStream() 访问响应。

    HttpWebRequest request = WebRequest.Create("http://google.com") as HttpWebRequest;
    
    //request.Accept = "application/xrds+xml";  
    HttpWebResponse response = (HttpWebResponse)request.GetResponse();
    
    WebHeaderCollection header = response.Headers;
    
    var encoding = ASCIIEncoding.ASCII;
    using (var reader = new System.IO.StreamReader(response.GetResponseStream(), encoding))
    {
        string responseText = reader.ReadToEnd();
    }
    

    【讨论】:

    • 请注意,这是假设为 ASCII 编码,这很可能是不正确的。
    • 还要注意WebHeaderCollection 行不是检索响应文本所必需的。
    • 还要注意,HTTP 响应没有包装在 using 块中。如果响应和下一个 using 块之间发生异常或返回,则不会关闭连接。
    • @Sam 感谢许多编辑尝试,但我担心您的编辑结果在很大程度上被许多用户否决(几个小时内有 6 个)。我已恢复您的更改,并将尝试改进答案。
    • 我确实有一个结果,其中包含HttpResponseContext,但我无法将文本读入对象(可理解的格式)例如:HttpResponseMessage response = wc.GetAsync(URI).Result;var contents = response.Content.ReadAsStringAsync(); 这里contents 变量包含一些随机数据,而不是必需的数据。
    【解决方案2】:

    The accepted answer 未正确处理 WebResponse 或解码文本。此外,在 .NET 4.5 中还提供了一种新方法。

    要执行 HTTP GET 并读取响应文本,请执行以下操作。

    .NET 1.1 - 4.0

    public static string GetResponseText(string address)
    {
        var request = (HttpWebRequest)WebRequest.Create(address);
    
        using (var response = (HttpWebResponse)request.GetResponse())
        {
            var encoding = Encoding.GetEncoding(response.CharacterSet);
    
            using (var responseStream = response.GetResponseStream())
            using (var reader = new StreamReader(responseStream, encoding))
                return reader.ReadToEnd();
        }
    }
    

    .NET 4.5

    private static readonly HttpClient httpClient = new HttpClient();
    
    public static async Task<string> GetResponseText(string address)
    {
        return await httpClient.GetStringAsync(address);
    }
    

    【讨论】:

    • 我假设您应该将 "http://google.com" 替换为参数名称 address?
    • 我非常喜欢这个答案。它是如此简洁和切中要害。它可以正确处理编码;与公认的答案不同。它还显示了如何访问响应 text,这也与接受的答案不同。
    • 此代码为我产生了死锁,如stackoverflow.com/a/10369275/1636247 中所述。它需要 .GetStringAsync(address).ConfigureAwait(false);在它起作用之前。
    【解决方案3】:

    我自己刚刚尝试过,它给了我一个 200 OK 响应,但没有内容 - 内容长度为 0。你确定它给你内容吗?无论如何,我会假设你真的很满意。

    获取实际文本依赖于知道编码,这可能很棘手。它应该在 Content-Type 标头中,但是你必须解析它等等。

    但是,如果这实际上是 XML(例如来自“http://google.com/xrds/xrds.xml”),那就容易多了。只需将 XML 加载到内存中,例如通过 LINQ 到 XML。例如:

    using System;
    using System.IO;
    using System.Net;
    using System.Xml.Linq;
    using System.Web;
    
    class Test
    {
        static void Main()
        {
            string url = "http://google.com/xrds/xrds.xml";
            HttpWebRequest request = (HttpWebRequest) WebRequest.Create(url);
    
            XDocument doc;
            using (WebResponse response = request.GetResponse())
            {
                using (Stream stream = response.GetResponseStream())
                {
                    doc = XDocument.Load(stream);
                }
            }
            // Now do whatever you want with doc here
            Console.WriteLine(doc);
        }   
    }
    

    如果内容是 XML,将结果放入 XML 对象模型(无论是 XDocumentXmlDocument 还是 XmlReader)可能比拥有纯文本更有价值。

    【讨论】:

    • 干杯。正是我想要的。
    • 您需要检查流是否为空吗? (reshaper 推荐)
    • 嗯,看反编译的方法也不清楚,为了安全起见,猜测是否为null
    • @CodeBlend:然后做什么?如果这是预期的情况,我想抛出一个异常......如果你将null 传递给XDocument.Load 会发生什么,所以IMO 没有任何好处。我通常不喜欢检查事情“以防万一,即使我认为它永远不可能做到这一点”。它有时间和地点,但如果你对每个方法都采用这种方法,你最终会陷入可怕的混乱。
    • @CodeBlend:好吧,如果你检查并发现它为空,你会怎么做?在大多数情况下,你基本上无法继续,所以你想抛出一个异常,说某些东西意外地为空 - 当然这就是 NullReferenceException 或 ArgumentNullException 将为你做的......
    【解决方案4】:
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://www.google.com");
    request.Method = "GET";
    HttpWebResponse response = (HttpWebResponse)request.GetResponse();
    
    Stream dataStream = response.GetResponseStream();
    StreamReader reader = new StreamReader(dataStream);
    string strResponse = reader.ReadToEnd();
    

    【讨论】:

    • 其他答案已经涵盖了这种方式。另外,我不认为这使用正确的编码来解码文本。
    【解决方案5】:

    这篇文章很好地概述了使用 HttpWebResponse 对象:How to use HttpWebResponse

    以下相关位:

    HttpWebResponse webresponse;
    
    webresponse = (HttpWebResponse)webrequest.GetResponse();
    
    Encoding enc = System.Text.Encoding.GetEncoding(1252);
    StreamReader loResponseStream = new StreamReader(webresponse.GetResponseStream(),enc);
    
    string Response = loResponseStream.ReadToEnd();
    
    loResponseStream.Close();
    webresponse.Close();
    
    return Response;
    

    【讨论】:

    • 如果网络服务器使用 Windows 代码页 1252 作为其编码,这是一个悲伤的一天 :( 你应该从响应中获取它......这很棘手。请参阅我的答案以了解解决方法特殊情况。
    • 噢!不是我的代码 :) 它来自文章,只是想通过给他提供相关位的快捷方式来提供帮助。帮助驾驶的危险:)
    【解决方案6】:

    response.GetResponseStream() 应该用于返回响应流。不要忘记close StreamResponse 对象。

    【讨论】:

      【解决方案7】:

      如果您的 http 请求是 Post 并且 request.Accept = "application/x-www-form-urlencoded"; 那么我认为您可以通过以下代码获取响应文本:

      var contentEncoding = response.Headers["content-encoding"];
                              if (contentEncoding != null && contentEncoding.Contains("gzip")) // cause httphandler only request gzip
                              {
                                  // using gzip stream reader
                                  using (var responseStreamReader = new StreamReader(new GZipStream(response.GetResponseStream(), CompressionMode.Decompress)))
                                  {
                                      strResponse = responseStreamReader.ReadToEnd();
                                  }
                              }
                              else
                              {
                                  // using ordinary stream reader
                                  using (var responseStreamReader = new StreamReader(response.GetResponseStream()))
                                  {
                                      strResponse = responseStreamReader.ReadToEnd();
                                  }
                              }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-10-26
        • 1970-01-01
        • 2017-12-18
        • 2014-06-15
        • 1970-01-01
        • 2020-11-04
        • 1970-01-01
        相关资源
        最近更新 更多