11+ Year IT Industry Experience, Working as Technical Lead with Capgemini | Consultant | Leadership and Corporate Trainer | Motivational and Technical Speaker | Career Coach | Author | MVP | Founder Of RVS Group | Trained more than 4000+ IT professionals | Azure | DevOps | ASP.NET | C# | MVC | WEB API | ANGULAR | TYPESCRIPT | MEAN | SQL | SSRS | WEB SERVICE | WCF... https://bikeshsrivastava.blogspot.in/ http://bikeshsrivastava.com/

How to upload multipart/form-data in web api 2

In this article I am going to disclose how to Upload multipart/form-data, picture,pdf,excel,etc.. to the server using Web API. Web API is essentially using as an mediator amongst client and server. It exposes the server side information to the client like (Website, Android , iPhone and etc..). The client can specifically communicate with the server using Web API. Web API exposes the server information as JSON.
Here, I will explain today how to make a Web API to upload images,document,ppt,multipart/form-data, etc. server. and save on local folder.
What is multipart/form-data?
enctype='multipart/form-data' means.that is the type of content-type that no characters will be encoded in content . that is why this type is used while uploading files client  to server. So multipart/form-data is used once  a form requires binary data in content, like the file document,etc..."

To upload multipart/form-data using WebApi follow some simple  steps which are  given below.
Step 1:- The first step is create a new project with MVC WebApi template name is "UploadDocsDummy" .see image...

In this image you can see i have selected both checkbox "MVC" and "WebApi",so you can select both or only "WebApi".
 After click on "Ok" yo can see this image which are given below.

According this image you can see there are model view and controller.so if you are beginner in MVC so learn architecture of MVC and flow.
Step 2:-Create a empty folder  "ClientDocument" in your application to save document/image ,etc.... You can see in next image which is already created.
Step 3:- Create a model class "InMemoryMultipartFormDataStreamProvider" inside model folder and use this code ,in this code i am configuring  multipart/form-data.
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Collections.ObjectModel;  
  4. using System.Collections.Specialized;  
  5. using System.IO;  
  6. using System.Linq;  
  7. using System.Net.Http;  
  8. using System.Net.Http.Headers;  
  9. using System.Threading.Tasks;  
  10. using System.Web;  
  11.   
  12. namespace UploadDocsDummy.Models  
  13. {  
  14.     public class InMemoryMultipartFormDataStreamProvider : MultipartStreamProvider  
  15.     {  
  16.         private NameValueCollection _formData = new NameValueCollection();  
  17.         private List<HttpContent> _fileContents = new List<HttpContent>();  
  18.   
  19.         // Set of indexes of which HttpContents we designate as form data  
  20.         private Collection<bool> _isFormData = new Collection<bool>();  
  21.   
  22.         /// <summary>  
  23.         /// Gets a <see cref="NameValueCollection"/> of form data passed as part of the multipart form data.  
  24.         /// </summary>  
  25.         public NameValueCollection FormData  
  26.         {  
  27.             get { return _formData; }  
  28.         }  
  29.   
  30.         /// <summary>  
  31.         /// Gets list of <see cref="HttpContent"/>s which contain uploaded files as in-memory representation.  
  32.         /// </summary>  
  33.         public List<HttpContent> Files  
  34.         {  
  35.             get { return _fileContents; }  
  36.         }  
  37.   
  38.         public override Stream GetStream(HttpContent parent, HttpContentHeaders headers)  
  39.         {  
  40.             // For form data, Content-Disposition header is a requirement  
  41.             ContentDispositionHeaderValue contentDisposition = headers.ContentDisposition;  
  42.             if (contentDisposition != null)  
  43.             {  
  44.                 // We will post process this as form data  
  45.                 _isFormData.Add(String.IsNullOrEmpty(contentDisposition.FileName));  
  46.   
  47.                 return new MemoryStream();  
  48.             }  
  49.   
  50.             // If no Content-Disposition header was present.  
  51.             throw new InvalidOperationException(string.Format("Did not find required '{0}' header field in MIME multipart body part..""Content-Disposition"));  
  52.         }  
  53.   
  54.         /// <summary>  
  55.         /// Read the non-file contents as form data.  
  56.         /// </summary>  
  57.         /// <returns></returns>  
  58.         public override async Task ExecutePostProcessingAsync()  
  59.         {  
  60.             // Find instances of non-file HttpContents and read them asynchronously  
  61.             // to get the string content and then add that as form data  
  62.             for (int index = 0; index < Contents.Count; index++)  
  63.             {  
  64.                 if (_isFormData[index])  
  65.                 {  
  66.                     HttpContent formContent = Contents[index];  
  67.                     // Extract name from Content-Disposition header. We know from earlier that the header is present.  
  68.                     ContentDispositionHeaderValue contentDisposition = formContent.Headers.ContentDisposition;  
  69.                     string formFieldName = UnquoteToken(contentDisposition.Name) ?? String.Empty;  
  70.   
  71.                     // Read the contents as string data and add to form data  
  72.                     string formFieldValue = await formContent.ReadAsStringAsync();  
  73.                     FormData.Add(formFieldName, formFieldValue);  
  74.                 }  
  75.                 else  
  76.                 {  
  77.                     _fileContents.Add(Contents[index]);  
  78.                 }  
  79.             }  
  80.         }  
  81.   
  82.         /// <summary>  
  83.         /// Remove bounding quotes on a token if present  
  84.         /// </summary>  
  85.         /// <param name="token">Token to unquote.</param>  
  86.         /// <returns>Unquoted token.</returns>  
  87.         private static string UnquoteToken(string token)  
  88.         {  
  89.             if (String.IsNullOrWhiteSpace(token))  
  90.             {  
  91.                 return token;  
  92.             }  
  93.   
  94.             if (token.StartsWith("\"", StringComparison.Ordinal) && token.EndsWith("\"", StringComparison.Ordinal) && token.Length > 1)  
  95.             {  
  96.                 return token.Substring(1, token.Length - 2);  
  97.             }  
  98.   
  99.             return token;  
  100.         }  
  101.   
  102.   
  103.   
  104.   
  105.   
  106.     }  
  107. }  
after that use this class in apicontroller.  
Step 4:- Create a new apiController "DocumentUploadController" inside controller folder.see image..
 Step 5:- If you have created a new controller "DocumentUpload" then create a new api (Action) "MediaUpload" like this.
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Collections.Specialized;  
  4. using System.IO;  
  5. using System.Linq;  
  6. using System.Net;  
  7. using System.Net.Http;  
  8. using System.Threading.Tasks;  
  9. using System.Web;  
  10. using System.Web.Configuration;  
  11. using System.Web.Http;  
  12. using UploadDocsDummy.Models;  
  13.   
  14. namespace UploadDocsDummy.Controllers  
  15. {  
  16.     public class DocumentUploadController : ApiController  
  17.     {  
  18.         /// <summary>  
  19.         /// Upload Document.....  
  20.         /// </summary>        
  21.         /// <returns></returns>  
  22.         [HttpPost]  
  23.         [Route("api/DocumentUpload/MediaUpload")]  
  24.         public async Task<HttpResponseMessage> MediaUpload()  
  25.         {  
  26.             // Check if the request contains multipart/form-data.  
  27.             if (!Request.Content.IsMimeMultipartContent())  
  28.             {  
  29.                 throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);  
  30.             }  
  31.   
  32.             var provider = await Request.Content.ReadAsMultipartAsync<InMemoryMultipartFormDataStreamProvider>(new InMemoryMultipartFormDataStreamProvider());  
  33.             //access form data  
  34.             NameValueCollection formData = provider.FormData;  
  35.             //access files  
  36.             IList<HttpContent> files = provider.Files;  
  37.   
  38.             HttpContent file1 = files[0];  
  39.             var thisFileName = file1.Headers.ContentDisposition.FileName.Trim('\"');  
  40.   
  41.             ////-------------------------------------For testing----------------------------------  
  42.             //to append any text in filename.  
  43.             //var thisFileName = file1.Headers.ContentDisposition.FileName.Trim('\"') + DateTime.Now.ToString("yyyyMMddHHmmssfff"); //ToDo: Uncomment this after UAT as per Jeeevan  
  44.   
  45.             //List<string> tempFileName = thisFileName.Split('.').ToList();  
  46.             //int counter = 0;  
  47.             //foreach (var f in tempFileName)  
  48.             //{  
  49.             //    if (counter == 0)  
  50.             //        thisFileName = f;  
  51.   
  52.             //    if (counter > 0)  
  53.             //    {  
  54.             //        thisFileName = thisFileName + "_" + DateTime.Now.ToString("yyyyMMddHHmmssfff") + "." + f;  
  55.             //    }  
  56.             //    counter++;  
  57.             //}  
  58.   
  59.             ////-------------------------------------For testing----------------------------------  
  60.   
  61.             string filename = String.Empty;  
  62.             Stream input = await file1.ReadAsStreamAsync();  
  63.             string directoryName = String.Empty;  
  64.             string URL = String.Empty;  
  65.             string tempDocUrl = WebConfigurationManager.AppSettings["DocsUrl"];  
  66.   
  67.             if (formData["ClientDocs"] == "ClientDocs")  
  68.             {  
  69.                 var path = HttpRuntime.AppDomainAppPath;  
  70.                 directoryName = System.IO.Path.Combine(path, "ClientDocument");  
  71.                 filename = System.IO.Path.Combine(directoryName, thisFileName);  
  72.   
  73.                 //Deletion exists file  
  74.                 if (File.Exists(filename))  
  75.                 {  
  76.                     File.Delete(filename);  
  77.                 }  
  78.   
  79.                 string DocsPath = tempDocUrl + "/" + "ClientDocument" + "/";  
  80.                 URL = DocsPath + thisFileName;  
  81.   
  82.             }  
  83.   
  84.   
  85.             //Directory.CreateDirectory(@directoryName);  
  86.             using (Stream file = File.OpenWrite(filename))  
  87.             {  
  88.                 input.CopyTo(file);  
  89.                 //close file  
  90.                 file.Close();  
  91.             }  
  92.   
  93.             var response = Request.CreateResponse(HttpStatusCode.OK);  
  94.             response.Headers.Add("DocsUrl", URL);  
  95.             return response;  
  96.         }  
  97.   
  98.     }  
  99. }  
In this code i have written code to save document in folder from multipart/form-data.also using "InMemoryMultipartFormDataStreamProvider"
  
Step 6:- Now we need to configure "DocsUrl" in web.config file. which are using in api code to get URL.
Don't forget to configure this.
  1. <appSettings>  
  2.     <add key="DocsUrl" value="http://localhost:51356" />  
  3.   </appSettings>  
 Now we are ready to test api, see image..
According above image i have created a key in web.config file and model,controller,folder.
 Step 7:-Run application and use postman to test web api.
 if you are not aware about postman click here.. other wise see image  how to configure postman to test webapi.

 you will put your route and use form-data and post the value and image,document.in postman.After configured all things click on send and see out put like this...see image...........

 In this image you see ,we are returning file URL in header .Image has been saved in "ClientDocument" Folder
I hope you are good to post multipart/form-data. You can download this project which are already i've done.
You have just read an article that categorized by title MVC / WEB API by title How to upload multipart/form-data in web api 2. You can bookmark this page with a URL https://bikeshsrivastava.blogspot.com/2016/09/part-36how-to-upload-multipartform-data.html. Thank You!
Author: Bikesh Srivastava - Tuesday, September 20, 2016

3 comments to "How to upload multipart/form-data in web api 2"

  1. Please Explain Token and refresh token based authentication using web api and existing sql database

    ReplyDelete
  2. Really nice blog post. provided helpful information. I hope that you will post more updates like this
    Dot net Course

    ReplyDelete

Life Is Complicated, But Now programmer Can Keep It Simple.