Ошибка при загрузке файла WEB API WCF (предварительный просмотр 6): невозможно записать больше байтов в буфер, чем настроенный максимальный размер буфера: 65536 - PullRequest
7 голосов
/ 30 января 2012

У меня реальная проблема с веб-интерфейсом WCF.

У меня есть простой метод, который загружает файл и сохраняет на диск.Я, кажется, установил все правильные параметры, но получаю сообщение об ошибке выше, когда я пытаюсь загрузить файл 2 МБ.

Код сервера:

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
    HttpServiceHostFactory _factory  = new HttpServiceHostFactory();

    var config = new HttpConfiguration() 
    { 
        EnableTestClient = true, 
        IncludeExceptionDetail = true,
        TransferMode = System.ServiceModel.TransferMode.Streamed,
        MaxReceivedMessageSize = 4194304,
        MaxBufferSize = 4194304    
    };

    _factory.Configuration = config;

    RouteTable.Routes.Add(new ServiceRoute("api/docmanage", _factory, typeof(WorksiteManagerApi)));
}

клиент:

HttpClientHandler httpClientHandler = new HttpClientHandler();
httpClientHandler.MaxRequestContentBufferSize = 4194304;

var byteArray = 
    Encoding.ASCII.GetBytes(ConnectionSettings.WebUsername + ":" + ConnectionSettings.WebPassword);

HttpClient httpClient = new HttpClient(httpClientHandler);
httpClient.DefaultRequestHeaders.Authorization = 
    new AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray));
httpClient.BaseAddress = new Uri(ConnectionSettings.WebApiBaseUrl);
httpClient.MaxResponseContentBufferSize = 4194304;

...

multipartFormDataContent.Add(new FormUrlEncodedContent(formValues));
multipartFormDataContent.Add(byteArrayContent);

var postTask = httpClient.PostAsync("api/docmanage/UploadFile", multipartFormDataContent);

Тогда на сервере:

[WebInvoke(Method = "POST")]
public HttpResponseMessage UploadFile(HttpRequestMessage request)
{
    // Verify that this is an HTML Form file upload request
    if (!request.Content.IsMimeMultipartContent("form-data"))
    {
        throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
    }

    // Create a stream provider for setting up output streams
    MultipartFormDataStreamProvider streamProvider = new MultipartFormDataStreamProvider();

    // Read the MIME multipart content using the stream provider we just created.
    IEnumerable<HttpContent> bodyparts = request.Content.ReadAsMultipart(streamProvider);

    foreach (var part in bodyparts)
    {
        switch (part.Headers.ContentType.MediaType)
        {
            case "application/octet-stream":
                if (part.Headers.ContentLength.HasValue)
                {
                    // BLOWS UP HERE:            
                    var byteArray = part.ReadAsByteArrayAsync().Result;

                    if (null == fileName)
                    {
                        throw new HttpResponseException(HttpStatusCode.NotAcceptable);
                    }
                    else
                    {
                        uniqueFileId = Guid.NewGuid().ToString();
                        string tempFilename = Path.GetTempPath() + @"\" + uniqueFileId + fileName;

                        using (FileStream fileStream = File.Create(tempFilename, byteArray.Length))
                        {
                            fileStream.Write(byteArray, 0, byteArray.Length); 
                        }
                    }

                }
                break;
        }
    }
}

Есть идеи?Я использую последний предварительный просмотр веб-API .... Я заметил, что многое отсутствует в документации поддержки, но кажется, что есть некоторый предел буфера, который я не могу найти, как указать, или игнорируется .....

Ответы [ 3 ]

4 голосов
/ 19 марта 2012

Одна из вещей, которая не прояснена в (отсутствие) документации для класса HttpContent, заключается в том, что внутренний буфер по умолчанию равен 64 КБ, поэтому любой контент, который не является потоком, будет выдавать исключение, которое вы видите, когда содержимое превышает 64Kb.

Чтобы обойти это, используйте следующее:

part.LoadIntoBufferAsync(bigEnoughBufferSize).Result();
var byteArray = part.ReadAsByteArrayAsync().Result;

Я предполагаю, что ограничение 64 КБ для буфера класса HttpContent используется для предотвращения выделения большого количества памяти на сервере. Интересно, будет ли вам лучше проходить через содержимое байтового массива как StreamContent? Таким образом, он все равно должен работать без увеличения размера буфера HttpContent.

1 голос
/ 31 января 2012

Вы установили maxRequestLength в web.config:

<httpRuntime maxRequestLength="10240" />
0 голосов
/ 11 марта 2013

Я боролся с подобной проблемой с WinFI WCF в течение нескольких дней, я пытался опубликовать файл размером 12 МБ, и я не мог понять, что происходит.Моей серверной стороной была служба WCF, размещенная в IIS;моя проблема была не в настройках WCF, а в том, что упомянул Тони.При размещении в IIS не забудьте увеличить этот параметр.В документации MS указано, что значение по умолчанию составляет 4 МБ, что объясняет, почему я могу публиковать файлы размером 400 КБ.

Надеюсь, что это поможет другим с такими же проблемами.

...