2012-01-30 10 views
6

Tôi gặp sự cố thực sự với api web của WCF.Lỗi với tệp tải lên WCF WEB API (Xem trước 6): Không thể ghi thêm byte vào bộ đệm so với kích thước bộ đệm tối đa được cấu hình: 65536

Tôi có một phương pháp đơn giản tải lên tệp và lưu vào đĩa. Tôi dường như đã thiết lập tất cả các params đúng, nhưng nhận được thông báo lỗi trên khi tôi cố gắng để tải lên một tập tin 2mb.

server Code:

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

khách hàng:

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

Sau đó, trên máy chủ:

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

Bất kỳ ý tưởng? Tôi đang sử dụng xem trước mới nhất của api web .... Tôi nhận thấy rất nhiều là mất tích từ các tài liệu hỗ trợ nhưng có vẻ như có một số giới hạn bộ đệm mà tôi không thể tìm hiểu làm thế nào để xác định hoặc đang bị bỏ qua .... .

+0

Khi đăng mã, hãy đảm bảo mã được định dạng để có thể đọc được càng tốt. Đó là thô lỗ để yêu cầu mọi người dành thời gian của họ chọn thông qua một mẫu được định dạng sai. –

+0

Bạn có bất kỳ mục nhập cấu hình nào trên máy chủ và ứng dụng khách không? Nếu vậy, bạn có thể gửi chúng quá – Rajesh

+0

để lại tất cả cấu hình cho mã chỉ ... bạn có thể xem thông số cấu hình được chuyển đến dịch vụ khi tạo (và trên máy khách) .... –

Trả lời

4

Một trong những điều mà không được làm sáng tỏ trong (thiếu) tài liệu cho lớp HttpContent là mặc định đệm nội bộ là 64K do đó, bất kỳ nội dung nào không phải là luồng sẽ ném ngoại lệ bạn thấy khi nội dung vượt quá 64Kb.

Cách xung quanh nó là sử dụng như sau:

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

Tôi đoán rằng giới hạn 64K trên bộ đệm của lớp HttpContent là có để ngăn ngừa đến nhiều bộ nhớ phân bổ occuring trên máy chủ. Tôi tự hỏi nếu bạn sẽ được tốt hơn đi qua các nội dung mảng byte như là một StreamContent? Bằng cách này, nó vẫn hoạt động mà không cần phải tăng kích thước bộ đệm HttpContent.

+0

Cảm ơn vì điều đó tôi sẽ cung cấp cho nó một đi vào thứ hai. –

+0

Cảm ơn vì điều này .. sắp xếp nó ra. Chỉ cần lấy tuổi trước khi tôi trở lại và xem xét lại mã ... cho phép chỉ nói có một lý do tôi trì hoãn tính năng phụ thuộc vào nó! –

1

bạn đã thiết lập các maxRequestLength trong web.config:

<httpRuntime maxRequestLength="10240" /> 
+0

Không có vấn đề gì với yêu cầu bên ... yêu cầu đến máy chủ ok ... vấn đề duy nhất xảy ra khi mã cố gắng đọc nội dung vào một mảng byte ... tại thời điểm này nó vi phạm giới hạn kích thước bộ đệm, mặc dù điều này đã được thiết lập rõ ràng khi dịch vụ được lưu trữ .... có cảm giác một lỗi của nó trong wcf .... –

0

Tôi gặp khó khăn với một vấn đề tương tự với WCF WinAPI trong vài ngày, tôi đã cố gắng đăng một tệp 12Mb và tôi không thể tìm ra những gì đang diễn ra. Phía máy chủ của tôi là một dịch vụ WCF được lưu trữ trong IIS; vấn đề của tôi không phải là thiết lập WCF nhưng những gì Toni đã đề cập. Khi lưu trữ trong IIS, hãy nhớ tăng cài đặt này. Tài liệu MS chỉ ra rằng giá trị mặc định là 4Mb, giải thích tại sao tôi có thể đăng các tệp 400Kb.

Hy vọng điều này sẽ giúp những người khác có cùng loại rắc rối.

Các vấn đề liên quan