2011-04-25 56 views

回答

-2

你可以做的是,在web.config中

<httpRuntime maxRequestLength="11000" /> 

11000 == 11 MB

+0

根据问题 – Onkelborg 2011-04-25 14:07:35

+0

在web.config中无法完成在稍后的 – Ivo 2011-04-25 15:07:09

4

看看http://bytes.com/topic/asp-net/answers/346534-how-i-can-get-httpruntime-section-page

有你如何去HttpRuntimeSection的实例访问。然后修改属性MaxRequestLength。

+0

+1中对其进行了编辑。 Btw,PROTIP:不要将null发送给'WebConfigurationManager.OpenWebConfiguration(path)'。 'If null,打开根Web.config'这个句子似乎并不意味着我期望的,我不得不发送“〜”以从根目录中的web.config中获取值。 – ANeves 2011-12-14 20:39:47

4

增加最大请求长度的替代方法是创建一个IHttpModule的实现。在BeginRequest处理程序中,获取HttpWorkerRequest以完全在您自己的代码中处理它,而不是让默认实现处理它。

这是一个基本的实现,将处理发布名为“dropbox.aspx”的任何文件的任何请求(在任意目录下,它是否存在与否):

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 

namespace Example 
{ 
    public class FileUploadModule: IHttpModule 
    { 
     #region IHttpModule Members 

     public void Dispose() {} 

     public void Init(HttpApplication context) 
     { 
      context.BeginRequest += new EventHandler(context_BeginRequest); 
     } 

     #endregion 

     void context_BeginRequest(object sender, EventArgs e) 
     { 
      HttpApplication application = (HttpApplication)sender; 
      HttpContext context = application.Context; 
      string filePath = context.Request.FilePath; 
      string fileName = VirtualPathUtility.GetFileName(filePath); 
      string fileExtension = VirtualPathUtility.GetExtension(filePath); 

      if (fileName == "dropbox.aspx") 
      { 
       IServiceProvider provider = (IServiceProvider)context; 
       HttpWorkerRequest wr = (HttpWorkerRequest)provider.GetService(typeof(HttpWorkerRequest)); 

       //HANDLE REQUEST HERE 
       //Grab data from HttpWorkerRequest instance, as reflected in HttpRequest.GetEntireRawContent method. 

       application.CompleteRequest(); //bypasses all other modules and ends request immediately 
      } 
     } 
    } 
} 

你可以使用类似的东西,例如,如果您正在实施文件上传器,并且您希望在接收到多部分内容流时处理该内容,则可以根据发布的表单字段执行身份验证,更重要的是,可以取消服务器端上的请求甚至在您收到任何文件数据之前。如果您可以在流中尽早确定上传未被授权,或者该文件太大或超过用户的Dropbox磁盘配额,则这可以节省大量时间。

这对于默认实现是不可能的,因为试图访问HttpRequest的Form属性将导致它尝试接收整个请求流,并完成MaxRequestLength检查。 HttpRequest对象有一个名为“GetEntireRawContent”的方法,只要需要访问内容,该方法就会被调用。该方法开始用下面的代码:

HttpRuntimeSection httpRuntime = RuntimeConfig.GetConfig(this._context).HttpRuntime; 
int maxRequestLengthBytes = httpRuntime.MaxRequestLengthBytes; 
if (this.ContentLength > maxRequestLengthBytes) 
{ 
    if (!(this._wr is IIS7WorkerRequest)) 
    { 
     this.Response.CloseConnectionAfterError(); 
    } 
    throw new HttpException(SR.GetString("Max_request_length_exceeded"), null, 0xbbc); 
} 

的一点是,你会被跳过的代码和实现自己的自定义内容长度检查来代替。如果您使用反射来看看“GetEntireRawContent”使用它作为一个模型实现的其余部分,你会看到,它主要执行以下操作:调用GetPreloadedEntityBody,检查是否有更多的加载通过调用IsEntireEntityBodyIsPreloaded,最后通过调用循环ReadEntityBody获取剩余的数据。由GetPreloadedEntityBody和ReadEntityBody读取的数据被转储到一个专用流中,一旦超过大小阈值,该流就会自动使用临时文件作为后备存储。

基本实现应该是这样的:

MemoryStream request_content = new MemoryStream(); 
int bytesRemaining = wr.GetTotalEntityBodyLength() - wr.GetPreloadedEntityBodyLength(); 
byte[] preloaded_data = wr.GetPreloadedEntityBody(); 
if (preloaded_data != null) 
    request_content.Write(preloaded_data, 0, preloaded_data.Length); 
if (!wr.IsEntireEntityBodyIsPreloaded()) //not a type-o, they use "Is" redundantly in the 
{ 
    int BUFFER_SIZE = 0x2000; //8K buffer or whatever 
    byte[] buffer = new byte[BUFFER_SIZE]; 
    while (bytesRemaining > 0) 
    { 
     bytesRead = wr.ReadEntityBody(buffer, Math.Min(bytesRemaining, BUFFER_SIZE)); //Read another set of bytes 
     bytesRemaining -= bytesRead; // Update the bytes remaining 
     request_content.Write(buffer, 0, bytesRead); // Write the chunks to the backing store (memory stream or whatever you want) 
    } 
    if (bytesRead == 0) //failure to read or nothing left to read 
     break; 
} 

在这一点上,你必须在一个MemoryStream您的整个请求。然而,而不是像下载的整个请求,我所做的是卸载认为“bytesRemaining”循环成具有“ReadEnough(INT MAX_INDEX)”方法,一类叫做需求从专业化的MemoryStream认为“负荷不够”到流中以访问正被访问的字节。

最终,该架构允许我直接将请求发送到解析器从存储器流中读取,并且根据需要的存储器流自动从工人请求加载更多的数据。我还实现了事件,以便在解析多部分内容流的每个元素时,会在每个新零件被识别时以及何时完全接收每个零件时触发事件。