将HTTP请求读入字节数组

41

我正在开发一个需要接收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[]字段中。

谢谢!

7个回答

65

最简单的方法是将它复制到一个 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
1
@加密:你可以自己实现非常相似的东西 - 我马上会编辑它... - Jon Skeet
那么,要将它转换为byte[],我只需要使用destination.ToArray吗? - Encryption
@加密:您可以在那个点使用答案第一部分中的代码。 - Jon Skeet

19

你可以直接使用WebClient来实现这个...

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

其中..是数据的URL地址。


1
请注意,DownloadData 不会为 4xx 和 5xx 抛出异常。 - Nathan

9
我使用 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();

基本上是已接受答案的副本,只是使用了“WebResponse”,而OP没有使用。 - vapcguy

1

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

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

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

代码写得不错,但它假定被获取的数据是字符串类型。如果是文件或其他需要保留为字节的东西,则不能这样做。我对此不会投赞成票也不会投反对票。 - vapcguy

0

对于所有那些当您的 context.Request.ContentLength 大于零的情况,您可以简单地执行以下操作:

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

0
这对我有效:
    MemoryStream ms = new MemoryStream();
    await HttpContext.Request.Body.CopyToAsync(ms);
    byte[] fileBytes = ms.ToArray();

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