【问题标题】:Read Http Request into Byte array将 Http 请求读入字节数组
【发布时间】:2012-04-14 11:06:09
【问题描述】:

我正在开发一个需要接受 HTTP Post 请求并将其读入字节数组以进行进一步处理的网页。我有点坚持如何做到这一点,而且我很难做到最好的方法是什么。到目前为止,这是我的代码:

 public override void ProcessRequest(HttpContext curContext)
    {
        if (curContext != null)
        {
            int totalBytes = curContext.Request.TotalBytes;
            string encoding = curContext.Request.ContentEncoding.ToString();
            int reqLength = curContext.Request.ContentLength;
            long inputLength = curContext.Request.InputStream.Length;
            Stream str = curContext.Request.InputStream;

         }
       }

我正在检查请求的长度及其等于 128 的总字节数。现在我只需要使用 Stream 对象将其转换为 byte[] 格式吗?我是否朝着正确的方向前进?不知道如何进行。任何建议都会很棒。我需要将整个 HTTP 请求放入 byte[] 字段。

谢谢!

【问题讨论】:

    标签: c# asp.net httpcontext system.web


    【解决方案1】:

    最简单的方法是将其复制到MemoryStream - 如果需要,然后调用ToArray

    如果您使用的是 .NET 4,那真的很简单:

    MemoryStream ms = new MemoryStream();
    curContext.Request.InputStream.CopyTo(ms);
    // If you need it...
    byte[] data = ms.ToArray();
    

    编辑:如果您不使用 .NET 4,您可以创建自己的 CopyTo 实现。这是一个作为扩展方法的版本:

    public static void CopyTo(this Stream source, Stream destination)
    {
        // TODO: Argument validation
        byte[] buffer = new byte[16384]; // For example...
        int bytesRead;
        while ((bytesRead = source.Read(buffer, 0, buffer.Length)) > 0)
        {
            destination.Write(buffer, 0, bytesRead);
        }
    }
    

    【讨论】:

    • 如果没有 .CopyTo 选项,我将如何使用内存流?
    • @Encryption:你可以自己实现一些非常相似的东西——我会在一分钟内编辑它......
    • 那么要将其放入 byte[] 中,我是否只需要 destination.ToArray?
    • @Encryption:此时您可以使用答案第一部分中的代码。
    【解决方案2】:
    class WebFetch
    {
    static void Main(string[] args)
    {
        // used to build entire input
        StringBuilder sb = new StringBuilder();
    
        // used on each read operation
        byte[] buf = new byte[8192];
    
        // prepare the web page we will be asking for
        HttpWebRequest request = (HttpWebRequest)
            WebRequest.Create(@"http://www.google.com/search?q=google");
    
        // execute the request
        HttpWebResponse response = (HttpWebResponse)
            request.GetResponse();
    
        // we will read data via the response stream
        Stream resStream = response.GetResponseStream();
    
        string tempString = null;
        int count = 0;
    
        do
        {
            // fill the buffer with data
            count = resStream.Read(buf, 0, buf.Length);
    
            // make sure we read some data
            if (count != 0)
            {
                // translate from bytes to ASCII text
                tempString = Encoding.ASCII.GetString(buf, 0, count);
    
                // continue building the string
                sb.Append(tempString);
            }
        }
        while (count > 0); // any more data to read?
    
        // print out page source
        Console.WriteLine(sb.ToString());
        Console.Read();
        }
    }
    

    【讨论】:

    • 不错的代码,但它假定要获取的数据是字符串数据。如果它是一个文件或其他需要保存为字节的东西,那么这不是这样做的方法。不过,我不会对此投赞成票或反对票。
    【解决方案3】:

    您可以使用 WebClient 来实现...

    WebClient c = new WebClient();
    byte [] responseData = c.DownloadData(..)
    

    .. 是数据的 URL 地址。

    【讨论】:

    • 请注意DownloadData 永远不会抛出 4xx 和 5xx 的异常
    【解决方案4】:

    我有一个函数可以做到这一点,通过发送响应流:

    private byte[] ReadFully(Stream input)
    {
        try
        {
            int bytesBuffer = 1024;
            byte[] buffer = new byte[bytesBuffer];
            using (MemoryStream ms = new MemoryStream())
            {
                int readBytes;
                while ((readBytes = input.Read(buffer, 0, buffer.Length)) > 0)
                {
                   ms.Write(buffer, 0, readBytes);
                }
                return ms.ToArray();
            }
        }
        catch (Exception ex)
        {
            // Exception handling here:  Response.Write("Ex.: " + ex.Message);
        }
    }
    

    既然你有Stream str = curContext.Request.InputStream;,那么你可以这样做:

    byte[] bytes = ReadFully(str);
    

    如果你这样做了:

    HttpWebRequest req = (HttpWebRequest)WebRequest.Create(someUri);
    req.Credentials = CredentialCache.DefaultCredentials;
    HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
    

    你可以这样称呼它:

    byte[] bytes = ReadFully(resp.GetResponseStream());
    

    【讨论】:

      【解决方案5】:

      我使用MemoryStreamResponse.GetResponseStream().CopyTo(stream)

      HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(url);
      myRequest.Method = "GET";
      WebResponse myResponse = myRequest.GetResponse();
      MemoryStream ms = new MemoryStream();
      myResponse.GetResponseStream().CopyTo(ms);
      byte[] data = ms.ToArray();
      

      【讨论】:

      • 基本上是已接受答案的副本,只使用了 OP 未使用的 WebResponse
      【解决方案6】:

      对于所有那些 context.Request.ContentLength 大于零的情况,您可以简单地这样做:

      byte[] contentBytes = context.Request.BinaryRead(context.Request.ContentLength);
      

      【讨论】:

        猜你喜欢
        • 2020-12-16
        • 2018-12-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-05-30
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多