Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET How read a multipart form data in Web API?

I send a multipart form data to my Web API like this:

string example = "my string";
HttpContent stringContent = new StringContent(example);
HttpContent fileStreamContent = new StreamContent(stream);
using (var client = new HttpClient())
{
    using (var content = new MultipartFormDataContent())
    {
         content.Add(stringContent, "example", "example");
         content.Add(fileStreamContent, "stream", "stream");
         var uri = "http://localhost:58690/api/method";
         HttpResponseMessage response = await client.PostAsync(uri, content);

and this is the Web API:

[HttpPost]
[Route("api/method")]
public async Task<HttpResponseMessage> Method()
    {
         // take contents and do something
    }

How read the string and the stream from request body in my Web API?

like image 912
Giobbo Avatar asked Nov 16 '16 12:11

Giobbo


4 Answers

This should help you get started:

 var uploadPath = HostingEnvironment.MapPath("/") + @"/Uploads";
 Directory.CreateDirectory(uploadPath);
 var provider = new MultipartFormDataStreamProvider(uploadPath);
 await Request.Content.ReadAsMultipartAsync(provider);

 // Files
 //
 foreach (MultipartFileData file in provider.FileData)
 {
     Debug.WriteLine(file.Headers.ContentDisposition.FileName);
     Debug.WriteLine("File path: " + file.LocalFileName);
 }

 // Form data
 //
 foreach (var key in provider.FormData.AllKeys)
 {
     foreach (var val in provider.FormData.GetValues(key))
     {
          Debug.WriteLine(string.Format("{0}: {1}", key, val));
     }
 }
like image 79
Big Daddy Avatar answered Nov 20 '22 17:11

Big Daddy


This is code i've used before to receive json data + an optional file:

var result = await Request.Content.ReadAsMultipartAsync();

var requestJson = await result.Contents[0].ReadAsStringAsync();
var request = JsonConvert.DeserializeObject<MyRequestType>(requestJson);

if (result.Contents.Count > 1)
{
    var fileByteArray = await result.Contents[1].ReadAsByteArrayAsync();
    ...
}

Its really neat that you can combine different types of data in a request like this.

Edit: an example of how to send this request:

let serialisedJson = JSON.stringify(anyObject);
let formData = new FormData();
formData.append('initializationData', serialisedJson);
// fileObject is an instance of File
if (fileObject) {
    // the 'jsonFile' name might cause some confusion: 
    // in this case, the uploaded file is actually a textfile containing json data
    formData.append('jsonFile', fileObject);
}

return new Promise((resolve, reject) => {
    let xhr = new XMLHttpRequest();
    xhr.open('POST', 'http://somewhere.com', true);
    xhr.onload = function(e: any) {
        if (e.target.status === 200) {
            resolve(JSON.parse(e.target.response));
        }
        else {
            reject(JSON.parse(e.target.response));
        }
    };
    xhr.send(formData);
});
like image 20
Davy Avatar answered Nov 20 '22 18:11

Davy


You can read content and get all file information (in my example image) without copying to local disk in this way:

public async Task<IHttpActionResult> UploadFile()
{
    if (!Request.Content.IsMimeMultipartContent())
    {
        return StatusCode(HttpStatusCode.UnsupportedMediaType);
    }        

    var filesReadToProvider = await Request.Content.ReadAsMultipartAsync();

    foreach (var stream in filesReadToProvider.Contents)
    {
        // Getting of content as byte[], picture name and picture type
        var fileBytes = await stream.ReadAsByteArrayAsync();
        var pictureName = stream.Headers.ContentDisposition.FileName;
        var contentType = stream.Headers.ContentType.MediaType;
    }
}
like image 8
nikola.maksimovic Avatar answered Nov 20 '22 19:11

nikola.maksimovic


For sending more than one file

        System.Web.HttpFileCollection hfc = System.Web.HttpContext.Current.Request.Files;

        //// CHECK THE FILE COUNT.
        for (int iCnt = 0; iCnt <= hfc.Count - 1; iCnt++)
        {
            System.Web.HttpPostedFile hpf = hfc[iCnt];
            string Image = UploadDocuments.GetDocumentorfileUri(hpf);
            UploadDocuments.UploadDocumentsIntoData(Image, hpf.FileName, id);

        }

Sending HTML Form Data in ASP.NET Web API: File Upload and Multipart MIME

like image 1
midhu458 Avatar answered Nov 20 '22 18:11

midhu458