I'm having a real problem with the WCF web api.
I have a simple method that uploads a file and saves to disk. I seem to have set all the right params, but get the above error message when I try to upload a 2mb file.
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)));
}
client:
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);
Then, on the server:
[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;
}
}
}
Any ideas? I am using the latest preview of the web api.... I noticed a lot is missing from the support documentation but it seems there is some buffer limit that I can't find out how to specify or is being ignored.....
One of the things that is not made clear in the (lack of) documentation for the HttpContent class is that the default internal buffer is 64K so any content that is not a stream will throw the exception you are seeing once the content exceeds 64Kb.
The way around it is to use the following:
part.LoadIntoBufferAsync(bigEnoughBufferSize).Result();
var byteArray = part.ReadAsByteArrayAsync().Result;
I presume that the 64K limit on the buffer of the HttpContent class is there for preventing to much memory allocation occuring on the server. I wonder if you would be better of passing through the byte array content as a StreamContent? This way it should still work without having to increase the HttpContent buffer size.
Have you set the maxRequestLength in web.config:
<httpRuntime maxRequestLength="10240" />
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With