ReadEntityBody的行为已更改。

6

我有一个HttpModule,作为文件上传模块,在将.NET Framework升级到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个回答

1
我们也遇到了这个问题,并不得不进行调整。实际上,在生产环境中,通常会返回少于16 KB 的数据,可能是因为在该环境下一次只有少量数据可用。
就个人而言,我认为这是4.5版本的一个错误,因为ReadEntityBody的行为没有记录返回少于请求的情况,所以这是从4.0到4.5的一个破坏性变化。
另一方面,Stream.Read明确记录了此行为:
“即使未到达流的末尾,实现也可以返回少于请求的字节数。”
因此,如果您从另一个角度来看,ReadEntityBodyStream.Read具有相同的API,并且应该期望具有相同的语义。在这种意义上,4.5(webengine4.dll)仅更改了实现,同时仍然满足相同的协议。

我的看法是,最坏的情况下这是一个破坏性变更,而最好的情况下它只是一个文档错误。有些人可能认为它两者都不是。你可以自己决定。

我没有动力去提交一个bug。如果从一开始就是这样工作的话,我可能会认为这很合理。可惜在预期的100%向后兼容的框架更新中出现了问题。这就是生活...


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

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