IIS Express 8 - Максимална разрешена дължина

В случай, че по-долу е твърде дълго, въпросът ми е дали IIS Express 8 във Visual Studio 2013 се подчинява на атрибута maxAllowedContentLength или има някаква приоритетна стойност, която предотвратява големи заявки


При отстраняване на грешки в някои извиквания на webapi срещу Visual Studio 2013, получавам тази грешка:

Maximum request length exceeded.

Търсих в интернет и всичко изглежда сочи към тези два конфигурационни записа:

IIS 6-: maxRequestLength
IIS 7+: maxAllowedContentLength

Добавих и двата тези конфигурационни записа към моя web.config със стойност 4294967295, просто за безопасност. Когато се опитам да се обадя на контролера, все още получавам грешката.

Това ме накара да си помисля, че изпращам някакво гигантско количество данни към сървъра, но fiddler ми казва следното:

Request Count:   1
Bytes Sent:      4,327,084      (headers:1,026; body:4,326,058)
Bytes Received:  3,808      (headers:434; body:3,374)

И виждайки как, 4,327,084 ‹ 4,294,967,295 чувствам, че не би трябвало да има проблеми с тази заявка.

Следващото място, което се сетих да потърся, е кодът на моя сървър:

if (!Request.Content.IsMimeMultipartContent())
{
    throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
}

var provider = new MultipartFormDataStreamProvider(@"C:\tmp", Int32.MaxValue);

var task = Request.Content.ReadAsMultipartAsync(provider).ContinueWith(t =>
{
    if (t.IsFaulted || t.IsCanceled)
        throw t.Exception;   // <== This gets thrown

Така че отново размерът на заявката е значително по-малък от размера на буфера за доставчика на поток от данни.

Така че накратко, нямам представа какво се случва. Заявката е доста голяма, но от това, което мога да кажа, няма причина това да се провали. Това причинено ли е от VS13/IIS Exp8? Или има нещо друго, което пропускам?

Благодаря предварително за всяка помощ, която можете да предложите.


Ето записа в конфигурацията, който казах, че ще предоставя

<requestLimits maxAllowedContentLength="4294967295" />

И ето пълното изключение

System.IO.IOException: Error reading MIME multipart body part. ---> System.Web.HttpException: Maximum request length exceeded.
   at System.Web.HttpBufferlessInputStream.ValidateRequestEntityLength()
   at System.Web.HttpBufferlessInputStream.GetPreloadedContent(Byte[] buffer, Int32& offset, Int32& count)
   at System.Web.HttpBufferlessInputStream.BeginRead(Byte[] buffer, Int32 offset, Int32 count, AsyncCallback callback, Object state)
   at System.IO.Stream.<BeginEndReadAsync>b__d(Stream stream, ReadWriteParameters args, AsyncCallback callback, Object state)
   at System.Threading.Tasks.TaskFactory`1.FromAsyncTrim[TInstance,TArgs](TInstance thisRef, TArgs args, Func`5 beginMethod, Func`3 endMethod)
   at System.IO.Stream.BeginEndReadAsync(Byte[] buffer, Int32 offset, Int32 count)
   at System.IO.Stream.ReadAsync(Byte[] buffer, Int32 offset, Int32 count, CancellationToken cancellationToken)
   at System.Web.Http.WebHost.SeekableBufferedRequestStream.<ReadAsync>d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at System.Net.Http.HttpContentMultipartExtensions.<MultipartReadAsync>d__8.MoveNext()
   --- End of inner exception stack trace ---
   at System.Net.Http.HttpContentMultipartExtensions.<MultipartReadAsync>d__8.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
   at System.Net.Http.HttpContentMultipartExtensions.<ReadAsMultipartAsync>d__0`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at BICWeb.webservices.controllers.FormsDesignerController.<Post>d__b.MoveNext() in c:\code\BIC_CORE\TRUNK\BIC\src\BICWeb\webservices\controllers\FormsDesignerController.cs:line 300

И вътрешното изключение

System.Web.HttpException (0x80004005): Maximum request length exceeded.
   at System.Web.HttpBufferlessInputStream.ValidateRequestEntityLength()
   at System.Web.HttpBufferlessInputStream.GetPreloadedContent(Byte[] buffer, Int32& offset, Int32& count)
   at System.Web.HttpBufferlessInputStream.BeginRead(Byte[] buffer, Int32 offset, Int32 count, AsyncCallback callback, Object state)
   at System.IO.Stream.<BeginEndReadAsync>b__d(Stream stream, ReadWriteParameters args, AsyncCallback callback, Object state)
   at System.Threading.Tasks.TaskFactory`1.FromAsyncTrim[TInstance,TArgs](TInstance thisRef, TArgs args, Func`5 beginMethod, Func`3 endMethod)
   at System.IO.Stream.BeginEndReadAsync(Byte[] buffer, Int32 offset, Int32 count)
   at System.IO.Stream.ReadAsync(Byte[] buffer, Int32 offset, Int32 count, CancellationToken cancellationToken)
   at System.Web.Http.WebHost.SeekableBufferedRequestStream.<ReadAsync>d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at System.Net.Http.HttpContentMultipartExtensions.<MultipartReadAsync>d__8.MoveNext()

person mrK    schedule 16.06.2015    source източник
comment
Числата ви са толкова големи, че може да се считат за невалидни и игнорирани. Или, не дай си боже, прелее. Задайте ги на 10M, което е достатъчно за тази заявка. И се уверете, че са в байтове, кой знае.   -  person usr    schedule 16.06.2015
comment
Само съвет, заменете throw t.Exception; с t.Wait(). Това се справя по-добре с грешката и не унищожава съхранения стек. Вероятно така или иначе не трябва да използвате ContinueWith и да използвате await.   -  person usr    schedule 16.06.2015
comment
@usr Да, използвах изчакване за известно време, но бях в режим на промяна на всичко и да видя дали нещо работи   -  person mrK    schedule 16.06.2015
comment
@usr Що се отнася до първия ви коментар, .Net всъщност извежда грешка в конфигурацията, ако препълните този запис. От MSDN стойността, която въведох, е максималната разрешена стойност и трябва да работи за това.   -  person mrK    schedule 16.06.2015
comment
Всъщност забравих нещо важно. Публикувайте пълното изключение ToString. Обикновено това е първото нещо, което питам, не знам защо съм забравил.   -  person usr    schedule 16.06.2015
comment
Превишаването на maxAllowedContentLength ще върне състояние 404.13. разбирате ли това Това ограничение е ограничение на IIS, струва ми се, проблемът ви е във вашето приложение. Може би MultipartFormDataStreamProvider има свои собствени ограничения.   -  person Peter Hahndorf    schedule 16.06.2015
comment
@usr Съжалявам, Visual Studio се срина два пъти при мен. Публикувах както изключението, така и вътрешното изключение   -  person mrK    schedule 16.06.2015
comment
@PeterHahndorf Не разбирам това, но webapi обработва ли това поведение по различен начин от манипулатора на ASP.Net? Ако не, може напълно да е MultipartFormDataStreamProvider, но интернет все още не е предоставил никакви ограничения за това.   -  person mrK    schedule 16.06.2015
comment
@mrK - maxAllowedContentLength няма нищо общо с ASP.Net, това е IIS нещо. Изключението е в System.Web.HttpBufferlessInputStream, което е ASP.Net. Не помня дали има отделна настройка за това.   -  person Peter Hahndorf    schedule 16.06.2015
comment
Има атрибут maxRequestLength на system.web/httpRuntime, по подразбиране е 4096, може да искате да разгледате това.   -  person Peter Hahndorf    schedule 16.06.2015


Отговори (2)


Нека да разгледаме кода, който хвърля:

private void ValidateRequestEntityLength()
{
    if (!this._disableMaxRequestLength && (this.Length > this._maxRequestLength))
    {
        if (!(this._context.WorkerRequest is IIS7WorkerRequest))
        {
            this._context.Response.CloseConnectionAfterError();
        }
        throw new HttpException(SR.GetString("Max_request_length_exceeded"), null, 0xbbc);
    }
}

ctor задава тези опции:

internal HttpBufferlessInputStream(HttpContext context, bool persistEntityBody, bool disableMaxRequestLength)
{
    this._context = context;
    this._persistEntityBody = persistEntityBody;
    this._disableMaxRequestLength = disableMaxRequestLength;
    HttpRuntimeSection httpRuntime = RuntimeConfig.GetConfig(this._context).HttpRuntime;
    this._maxRequestLength = httpRuntime.MaxRequestLengthBytes;
    this._fileThreshold = httpRuntime.RequestLengthDiskThresholdBytes;
    if (this._persistEntityBody)
    {
        this._rawContent = new HttpRawUploadedContent(this._fileThreshold, this._context.Request.ContentLength);
    }
    int contentLength = this._context.Request.ContentLength;
    this._remainingBytes = (contentLength > 0) ? contentLength : 0x7fffffff;
    this._length = contentLength;
}

И можете да използвате тази HttpRequest функция, за да деактивирате ограничението:

public Stream GetBufferlessInputStream(bool disableMaxRequestLength)
{
    return this.GetInputStream(false, disableMaxRequestLength);
}

Ако искате да знаете как се изчислява ограничението на байтовете, декомпилирайте httpRuntime.MaxRequestLengthBytes.

person usr    schedule 16.06.2015
comment
Така че всичко това се прави в WebAPI контролер, така че Request всъщност е HttpRequestMessage вместо HttpRequest. Изглежда, че HttpRequestMessage няма GetBufferlessInputStream метод. - person mrK; 16.06.2015
comment
Всъщност с малко помощ от това успях да го накарам да работи. Благодаря за цялата помощ! stackoverflow.com/ въпроси/25753248/ - person mrK; 16.06.2015

само мисъл, но от: http://www.smarterasp.net/support/kb/a1544/how-to-resolve-maximum-request-length-exceeded.aspx

"maxAllowedContentLength се измерва в байтове, докато maxRequestLength се измерва в килобайтове"

проверете дали и двете са настроени правилно и опитайте отново

person AaronReynoldsUK    schedule 16.06.2015
comment
Във всеки случай те трябва да бъдат настроени правилно. Ще актуализирам публикацията си с действителната стойност на конфигурацията - person mrK; 16.06.2015