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); } });
Blogs I've looked at:
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) { } }
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.
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.
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); } });
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