从C#代码增加Http Runtime MaxRequestLength

时间:2011-04-25 13:09:01

标签: asp.net

如何增加

来自我的C#代码?我无法在Web.config中执行此操作,我的应用程序是为部署Web而创建的 IIS中的应用程序。

3 个答案:

答案 0 :(得分:4)

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

您可以访问HttpRuntimeSection的实例。然后修改属性MaxRequestLength。

答案 1 :(得分: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
            }
        }
    }
}

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

这与默认实现无关,因为尝试访问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”的其余部分以将其用作模型实现,您将看到它基本上执行以下操作:调用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调用的。进入流来访问正在访问的字节。

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

答案 2 :(得分:-2)

您可以在web.config

中执行此操作
<httpRuntime maxRequestLength="11000" />

11000 == 11 mb