6

我有一个充当文件上传模块的 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);

        // ......
    }
4

2 回答 2

1

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

就个人而言,我将此视为 4.5 错误,因为未记录ReadEntityBody的行为返回少于请求的值,因此这是从 4.​​0 到 4.5 的重大更改。

另一方面,Stream.Read确实明确记录了这种行为:

即使没有到达流的末尾,实现也可以自由地返回比请求更少的字节。

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

IMO,在最坏的情况下这是一个重大变化,而在最好的情况下它是一个文档错误。有些人可能两者都不考虑。你可以决定。

我没有动力提交错误。如果它从第一天起就以这种方式工作,我可能会认为它是合乎逻辑的。遗憾的是,它在预期的 100% 向后兼容的框架更新中中断了。这就是生活..

于 2013-02-06T17:40:29.593 回答
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);
    }
}
于 2013-02-13T10:17:21.970 回答