2013-01-06 74 views
6

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

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

     // ...... 
    } 

回答

1

我们也遇到过这个问题,不得不进行调整。实际上,在生产环境中,我们发现通常可以返回少于16 KB的数据,这可能是因为在该环境中一次只能使用较少的数据。

就我个人而言,我将此视为4.5错误,因为ReadEntityBody的行为没有记录为返回小于请求的行为,所以这是从4.0到4.5的突变。

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

的实现可自由地返回比,即使尚未达到要求的流的末尾更少的字节。

所以,如果你从另一个角度看,ReadEntityBody具有相同的API Stream.Read,应该预计将有相同的语义。从这个意义上讲,4.5(webengine4.dll)只是改变了实现,同时仍然履行了同样的合同。

国际海事组织,在最坏的情况下,这是一个突破性的变化,而充其量也是一个文件错误。有些人可能认为它不是。你可以决定。

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

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