从c#代码中增加Http运行时MaxRequestLength



如何增加

从我的c#代码?我不能在Web上这样做。我的应用程序是用来部署web的

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

这就是访问HttpRuntimeSection实例的方法。然后修改属性MaxRequestLength

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

这是一个基本的实现,它将处理任何发送到任何名为"dropbox"的文件的请求。(在任何目录下,无论是否存在):

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

关键是您将跳过该代码并实现您自己的自定义内容长度检查。如果你使用Reflector来查看"GetEntireRawContent"的其余部分,并将其用作模型实现,你会看到它基本上做了以下事情:调用getpreloaddentybody,通过调用iswholentitybodyispreloaded检查是否有更多的要加载,最后循环调用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按需调用,该MemoryStream"加载足够"到流中以访问被访问的字节。

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

你可以在web.config

<httpRuntime maxRequestLength="11000" />

11000 == 11mb

最新更新