C# 文件上载WCF WEB API时出错(预览6):向缓冲区写入的字节数不能超过配置的最大缓冲区大小65536
我对WCFWebAPI有一个真正的问题 我有一个简单的方法上传文件并保存到磁盘。我似乎已经设置了所有正确的参数,但当我尝试上载2mb文件时,会收到上面的错误消息 服务器代码:C# 文件上载WCF WEB API时出错(预览6):向缓冲区写入的字节数不能超过配置的最大缓冲区大小65536,c#,asp.net,wcf,httpclient,wcf-web-api,C#,Asp.net,Wcf,Httpclient,Wcf Web Api,我对WCFWebAPI有一个真正的问题 我有一个简单的方法上传文件并保存到磁盘。我似乎已经设置了所有正确的参数,但当我尝试上载2mb文件时,会收到上面的错误消息 服务器代码: public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); HttpServiceHostFactory _factory = new HttpS
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;
}
}
}
[WebInvoke(Method=“POST”)]
公共HttpResponseMessage上载文件(HttpRequestMessage请求)
{
//确认这是一个HTML表单文件上传请求
if(!request.Content.IsMimeMultipartContent(“表单数据”))
{
抛出新的HttpResponseException(HttpStatusCode.UnsupportedMediaType);
}
//创建用于设置输出流的流提供程序
MultipartFormDataStreamProvider streamProvider=新的MultipartFormDataStreamProvider();
//使用我们刚刚创建的流提供程序读取MIME多部分内容。
IEnumerable bodyparts=request.Content.ReadAsMultipart(streamProvider);
foreach(车身零件中的var零件)
{
开关(part.Headers.ContentType.MediaType)
{
案例“应用程序/八位字节流”:
if(part.Headers.ContentLength.HasValue)
{
//在这里爆炸:
var byteArray=part.ReadAsByteArrayAsync().Result;
if(null==文件名)
{
抛出新的HttpResponseException(HttpStatusCode.NotAcceptable);
}
其他的
{
uniqueFileId=Guid.NewGuid().ToString();
字符串tempFilename=Path.GetTempPath()++“\”+uniqueFileId+fileName;
使用(FileStream FileStream=File.Create(tempFilename,byteArray.Length))
{
Write(byteArray,0,byteArray.Length);
}
}
}
打破
}
}
}
有什么想法吗?我正在使用web api的最新预览。。。。我注意到支持文档中缺少很多内容,但似乎存在一些缓冲区限制,我无法确定如何指定或被忽略……是否在web.config中设置了maxRequestLength:
<httpRuntime maxRequestLength="10240" />
HttpContent类的(缺少)文档中没有明确说明的一点是,默认的内部缓冲区是64K,因此任何非流的内容都会在内容超过64Kb时抛出异常 解决方法是使用以下方法:
part.LoadIntoBufferAsync(bigEnoughBufferSize).Result();
var byteArray = part.ReadAsByteArrayAsync().Result;
我假设HttpContent类缓冲区上的64K限制是为了防止在服务器上发生过多的内存分配。我想知道您是否会更好地将字节数组内容作为StreamContent传递?这样,在不增加HttpContent缓冲区大小的情况下,它仍然可以工作。几天来,我一直在努力解决WCF WinAPI的类似问题,当时我试图发布一个12Mb的文件,但我不知道发生了什么。我的服务器端是托管在IIS中的WCF服务;我的问题不是WCF设置,而是Toni提到的。在IIS中托管时,请记住增加此设置。MS文档表明默认值为4Mb,这解释了为什么我可以发布400Kb的文件
希望这能帮助其他有同样问题的人。发布代码时,请确保其格式尽可能可读。要求人们花时间挑选格式不正确的样本是不礼貌的。您在服务器和客户端上有任何配置条目吗?如果是这样的话,那么你能把它们发布到tooleft上吗?把所有的配置只发布到代码中。。。您可以看到在创建时(以及在客户端)将配置参数传递给服务…在请求端这不是问题。。。请求到达服务器正常。。。当代码试图将内容读入字节数组时,唯一的问题就会出现。。。在这一点上,它违反了缓冲区大小限制,即使这是在服务托管时明确设置的…感觉它是wcf中的一个bug…谢谢,我将在周一尝试一下。谢谢。。把它整理好。我花了很长时间才回来重温代码。。。让我们只说我延迟依赖它的功能是有原因的!