文件上载WCF WEB API时出错(预览6):无法向缓冲区写入超过配置的最大缓冲区大小65536的字节

本文关键字:缓冲区 字节 配置 65536 API WEB WCF 上载 出错 预览 文件 | 更新日期: 2023-09-27 18:21:58

我在WCF web api方面遇到了一个真正的问题。

我有一个简单的方法,上传一个文件并保存到磁盘。我似乎已经设置了所有正确的参数,但当我尝试上传2mb文件时,会收到上面的错误消息。

服务器代码:

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

有什么想法吗?我正在使用web api的最新预览。。。。我注意到支持文档中缺少了很多内容,但似乎有一些缓冲区限制,我找不到如何指定,或者被忽略了。。。。。

文件上载WCF WEB API时出错(预览6):无法向缓冲区写入超过配置的最大缓冲区大小65536的字节

HttpContent类的文档中没有明确的一点是,默认的内部缓冲区是64K,因此一旦内容超过64Kb,任何非流的内容都会引发异常。

绕过它的方法是使用以下方法:

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

我认为HttpContent类缓冲区的64K限制是为了防止服务器上发生过多的内存分配。我想知道您是否更适合将字节数组内容作为StreamContent进行传递?这样,它应该仍然可以工作,而不必增加HttpContent缓冲区的大小。

是否在web.config中设置了maxRequestLength:

<httpRuntime maxRequestLength="10240" />

几天来,我一直在努力解决WCF WinAPI的类似问题,我试图发布一个12Mb的文件,但我不知道发生了什么。我的服务器端是IIS中托管的WCF服务;我的问题不是WCF设置,而是托尼提到的。在IIS中托管时,请记住增加此设置。MS文档显示默认值为4Mb,这解释了为什么我可以发布400Kb的文件。

希望这能帮助其他遇到同样麻烦的人。