How would i go about using MultipartFormDataStreamProvider
and Request.Content.ReadAsMultipartAsync
in a ApiController
?
I have googled a few tutorials but I can't get any of them to work, I'm using .net 4.5.
Code:
public class TestController : ApiController
{
const string StoragePath = @"T:\WebApiTest";
public async void Post()
{
if (Request.Content.IsMimeMultipartContent())
{
var streamProvider = new MultipartFormDataStreamProvider(Path.Combine(StoragePath, "Upload"));
await Request.Content.ReadAsMultipartAsync(streamProvider);
foreach (MultipartFileData fileData in streamProvider.FileData)
{
if (string.IsNullOrEmpty(fileData.Headers.ContentDisposition.FileName))
throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotAcceptable, "This request is not properly formatted"));
string fileName = fileData.Headers.ContentDisposition.FileName;
if (fileName.StartsWith("\"") && fileName.EndsWith("\""))
fileName = fileName.Trim('"');
if (fileName.Contains(@"/") || fileName.Contains(@"\"))
fileName = Path.GetFileName(fileName);
File.Copy(fileData.LocalFileName, Path.Combine(StoragePath, fileName));
}
}
else
{
throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotAcceptable, "This request is not properly formatted"));
}
}
}
I get the exception
Unexpected end of MIME multipart stream. MIME multipart message is not complete.
when the await task;
runs.
Does anyone know what I am doing wrong or have a working example in asp.net?
An IMultipartStreamProvider suited for use with HTML file uploads for writing file content to a FileStream. The stream provider looks at the <b>Content-Disposition</b> header field and determines an output Stream based on the presence of a <b>filename</b> parameter.
Description. ReadAsMultipartAsync(HttpContent) Reads all body parts within a MIME multipart message and produces a set of HttpContent instances as a result. ReadAsMultipartAsync(HttpContent, CancellationToken) Reads all body parts within a MIME multipart message and produces a set of HttpContent instances as a result.
I resolved the error, i don't understand what this has to do with end of multipart stream but here is the working code:
public class TestController : ApiController
{
const string StoragePath = @"T:\WebApiTest";
public async Task<HttpResponseMessage> Post()
{
if (Request.Content.IsMimeMultipartContent())
{
var streamProvider = new MultipartFormDataStreamProvider(Path.Combine(StoragePath, "Upload"));
await Request.Content.ReadAsMultipartAsync(streamProvider);
foreach (MultipartFileData fileData in streamProvider.FileData)
{
if (string.IsNullOrEmpty(fileData.Headers.ContentDisposition.FileName))
{
return Request.CreateResponse(HttpStatusCode.NotAcceptable, "This request is not properly formatted");
}
string fileName = fileData.Headers.ContentDisposition.FileName;
if (fileName.StartsWith("\"") && fileName.EndsWith("\""))
{
fileName = fileName.Trim('"');
}
if (fileName.Contains(@"/") || fileName.Contains(@"\"))
{
fileName = Path.GetFileName(fileName);
}
File.Move(fileData.LocalFileName, Path.Combine(StoragePath, fileName));
}
return Request.CreateResponse(HttpStatusCode.OK);
}
else
{
return Request.CreateResponse(HttpStatusCode.NotAcceptable, "This request is not properly formatted");
}
}
}
At first, you should define enctype to multipart/form-data in ajax request header.
[Route("{bulkRequestId:int:min(1)}/Permissions")]
[ResponseType(typeof(IEnumerable<Pair>))]
public async Task<IHttpActionResult> PutCertificatesAsync(int bulkRequestId)
{
if (Request.Content.IsMimeMultipartContent("form-data"))
{
string uploadPath = HttpContext.Current.Server.MapPath("~/uploads");
var streamProvider = new MyStreamProvider(uploadPath);
await Request.Content.ReadAsMultipartAsync(streamProvider);
List<Pair> messages = new List<Pair>();
foreach (var file in streamProvider.FileData)
{
FileInfo fi = new FileInfo(file.LocalFileName);
messages.Add(new Pair(fi.FullName, Guid.NewGuid()));
}
//if (_biz.SetCertificates(bulkRequestId, fileNames))
//{
return Ok(messages);
//}
//return NotFound();
}
return BadRequest();
}
public class MyStreamProvider : MultipartFormDataStreamProvider
{
public MyStreamProvider(string uploadPath) : base(uploadPath)
{
}
public override string GetLocalFileName(HttpContentHeaders headers)
{
string fileName = Guid.NewGuid().ToString() + Path.GetExtension(headers.ContentDisposition.FileName.Replace("\"", string.Empty));
return fileName;
}
}
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