Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Post JSON with data AND file to Web Api - jQuery / MVC

I need to post to an Api Controller w/ JSON (preferably) with ONE request.

The issue is passing data AND a file (image uploaded). My property is coming up empty (null).

I've looked at quite a bit of blogs but can't seem to get the image's data passed.

public class SomeModel {     public string Name { get; set; }     public string Email { get; set; }     public string City { get; set; }     public HttpPostedFileBase Image { get; set; }     public string Title { get; set; }     public string Description { get; set; }     public string CountryCode { get; set; } }       [HttpPost]     public void CreateContestEntry(SomeModel model)     {         // model.Image is always null         // .. get image here - the other properties no issues     } 

jQuery

    // create model for controller     var model = {         Name: $.trim($contestForm.find('[name="nombre"]').val()) + ' ' + $.trim($contestForm.find('[name="apellido"]').val()),         Email: $.trim($contestForm.find('[name="email"]').val().toLowerCase()),         City: $.trim($contestForm.find('[name="cuidad"]').val()),         Title: $.trim($contestForm.find('[name="title"]').val()),         Description: $.trim($contestForm.find('[name="description"]').val()),         CountryCode: 'co',         Image: $contestForm.find('[name="file-es"]')[0].files[0]  // this has the file for sure     };      $.ajax({         url: '/Umbraco/api/ControllerName/CreateContestEntry',         type: 'POST',         dataType: 'json',         data: JSON.stringify(model),         //data: $('#test-form').serialize(),  // tried this and using FormData()         processData: false,         async: false,         contentType: 'application/json; charset=utf-8',         complete: function (data) {          },         error: function (response) {             console.log(response.responseText);         }     }); 

enter image description here

Blogs I've looked at:

  • File Upload with Additonal Form Data to Web Api from MVC
  • http://www.asp.net/web-api/overview/advanced/sending-html-form-data,-part-1
  • http://www.asp.net/web-api/overview/advanced/sending-html-form-data,-part-2
  • Custom form data with multiple files to Web API controller

When I tried the FormData and $('#form1').serialize() approach, my provider.FileData and provider.FormData were always empty as well. I removed the model param from the method and the breakpoints were hitting when I switched it up.

    [HttpPost]     public void CreateContestEntry()     {         string root = HttpContext.Current.Server.MapPath("~/App_Data");         var provider = new MultipartFormDataStreamProvider(root);          try         {             // Read the form data.             Request.Content.ReadAsMultipartAsync(provider);              // This illustrates how to get the file names.             foreach (MultipartFileData file in provider.FileData)             {                 // empty             }              foreach (var key in provider.FormData.AllKeys)             {                 foreach (var val in provider.FormData.GetValues(key))                 {                     // empty                 }             }             //return Request.CreateResponse(HttpStatusCode.OK);         }         catch(Exception ex)         {          }     } 

SOLUTION:

Going off of @Musa's answer, here's the Api Controller code. I mapped the NameValueCollection to my model.

    [HttpPost]     public void CreateContestEntry()     {         try         {             // get variables first             NameValueCollection nvc = HttpContext.Current.Request.Form;             var model = new WAR2015ContestModel();              // iterate through and map to strongly typed model             foreach (string kvp in nvc.AllKeys)             {                 PropertyInfo pi = model.GetType().GetProperty(kvp, BindingFlags.Public | BindingFlags.Instance);                 if (pi != null)                 {                     pi.SetValue(model, nvc[kvp], null);                 }             }              model.Image = HttpContext.Current.Request.Files["Image"];         }         catch(Exception ex)         {          }     } 
like image 519
Rob Scott Avatar asked May 27 '15 18:05

Rob Scott


People also ask

How can we post data in a JSON format to a Web API from a MVC controller?

You need to use JSON. stringify method to convert it to JSON string when you send it, And the model binder will bind the json data to your class object. contentType property tells the server that we are sending the data in JSON format.

How do I post JSON data to API using C#?

To post JSON to a REST API endpoint using C#/. NET, you must send an HTTP POST request to the REST API server and provide JSON data in the body of the C#/. NET POST message. You also need to specify the data type in the body of the POST message using the Content-Type: application/json request header.


1 Answers

You can't upload a file(that is arbitrary binary data) with JSON as JSON is a text format. you'll have to use multipart form data.

// create model for controller var model = new FormData(); model.append('Name', $.trim($contestForm.find('[name="nombre"]').val()) + ' ' + $.trim($contestForm.find('[name="apellido"]').val())); model.append('Email', $.trim($contestForm.find('[name="email"]').val().toLowerCase())); model.append('City', $.trim($contestForm.find('[name="cuidad"]').val())); model.append('Title', $.trim($contestForm.find('[name="title"]').val())); model.append('Description', $.trim($contestForm.find('[name="description"]').val())); model.append('CountryCode', 'co'); model.append('Image', $contestForm.find('[name="file-es"]')[0].files[0]);  // this has the file for sure  $.ajax({     url: '/Umbraco/api/ControllerName/CreateContestEntry',     type: 'POST',     dataType: 'json',     data: model,     processData: false,     contentType: false,// not json     complete: function (data) {         var mediaId = $.parseJSON(data.responseText); //?      },     error: function (response) {         console.log(response.responseText);     } }); 
like image 187
Musa Avatar answered Sep 27 '22 18:09

Musa