ReadEntityBody改变了行为

时间:2013-01-06 21:42:42

标签: c# asp.net

我有一个HttpModule充当文件上传模块,在将.NET框架升级到4.5后,它的工作方式不同。使用框架4.0,ReadEntityBody方法用256k填充数组,但在升级之后它只返回16k。还有其他人有这个问题吗?

    public void ProcessRequest(HttpContext context)
    {
        IServiceProvider provider = (IServiceProvider)context;
        HttpWorkerRequest worker = (HttpWorkerRequest)provider.GetService(
            typeof(HttpWorkerRequest));

        byte[] data = new byte[256 * 1024];
        int readData = worker.ReadEntityBody(data, data.Length);

        // ......
    }

2 个答案:

答案 0 :(得分:1)

我们也遇到过这种情况,不得不进行调整。事实上,在生产中我们发现通常也可以返回少于16 KB,可能是因为在该环境中一次可用的数量较少。

就个人而言,我将此视为4.5错误,因为ReadEntityBody的行为未记录为返回少于请求的内容,因此这是从4.0更改为4.5。

另一方面,Stream.Read会明确记录此行为:

  

即使尚未到达流的末尾,实现也可以自由返回少于请求的字节数。

因此,如果从另一个角度来看,ReadEntityBody具有与Stream.Read相同的API,并且应该具有相同的语义。从这个意义上说,4.5(webengine4.dll)只是改变了实现,同时仍然履行了相同的合同。

IMO,在最糟糕的情况下,它是一个突破性的变化,而充其量只是一个文档错误。有些人可能也不会考虑它。你可以决定。

我没有动机提交错误。如果它从第1天开始以这种方式工作,我可能会认为它合乎逻辑。它打破了预期的100%向后兼容的框架更新,这简直是一种耻辱。 C'est la vie ..

答案 1 :(得分:0)

最后我找到了解决这个问题的方法。为HttpWorkerRequestExtension类创建了一个扩展,它将在返回我的调用之前填充缓冲区。

public static class HttpWorkerRequestExtension
{
    public static int ReadEntityBodyEx(this HttpWorkerRequest request, byte[] buffer, int offset, int size)
    {
        int bytesRead = 0;
        int totalBytesRead = 0;
        int bytesToRead = size;

        while (bytesToRead > 0)
        {
            bytesRead = request.ReadEntityBody(buffer, offset + totalBytesRead, size - totalBytesRead);

            if (bytesRead == 0) { break; }

            bytesToRead -= bytesRead;
            totalBytesRead += bytesRead;
        }

        return totalBytesRead;
    }

    public static int ReadEntityBodyEx(this HttpWorkerRequest request, byte[] buffer, int size)
    {
        return request.ReadEntityBodyEx(buffer, 0, size);
    }
}