Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to do a ASP.NET MVC Ajax form post with multipart/form-data?

I am working on a ASP.NET MVC web site which has a form that allows for the upload of files using the multipart/form data enctype option on the form tag like so

<form enctype="multipart/form-data" method="post" action='<%= Url.Action("Post","Entries",new {id=ViewData.Model.MemberDetermination.DeterminationMemberID})  %>'> 

How would I write this to do an ASP.NET MVC Ajax form post instead?

like image 949
dswatik Avatar asked Feb 24 '09 13:02

dswatik


2 Answers

It is possible but it's a long way. Step 1: write your form

ex:

@using (Ajax.BeginForm(YourMethod, YourController, new { id= Model.Id }, new AjaxOptions {//needed options }, new { enctype = "multipart/form-data" })) {     <input type="file" id="image" name="image" />     <input type="submit" value="Modify" /> } 

Step 2: intercept the request and send it to the server

<script type="text/javascript">     $(function() {         $("#form0").submit(function(event) {             var dataString;             event.preventDefault();             var action = $("#form0").attr("action");             if ($("#form0").attr("enctype") == "multipart/form-data") {                 //this only works in some browsers.                 //purpose? to submit files over ajax. because screw iframes.                 //also, we need to call .get(0) on the jQuery element to turn it into a regular DOM element so that FormData can use it.                 dataString = new FormData($("#form0").get(0));                 contentType = false;                 processData = false;             } else {                 // regular form, do your own thing if you need it             }             $.ajax({                 type: "POST",                 url: action,                 data: dataString,                 dataType: "json", //change to your own, else read my note above on enabling the JsonValueProviderFactory in MVC                 contentType: contentType,                 processData: processData,                 success: function(data) {                     //BTW, data is one of the worst names you can make for a variable                     //handleSuccessFunctionHERE(data);                 },                 error: function(jqXHR, textStatus, errorThrown) {                     //do your own thing                     alert("fail");                 }             });         }); //end .submit()     }); </script> 

Step 3: Because you make an ajax call you probably want to replace some image or something of multipart/form-data

ex:

handleSuccessFunctionHERE(data) {     $.ajax({         type: "GET",         url: "/Profile/GetImageModified",         data: {},         dataType: "text",         success: function (MSG) {             $("#imageUploaded").attr("src", "data:image/gif;base64,"+msg);         },         error: function (msg) {             alert(msg);         }     }); } 

The MSG variable is an base64 encrypted string. In my case it's the source of the image.

In this way I managed to change a profile picture and after that the picture is immediately updated. Also make sure you add in Application_Start (global.asax) ValueProviderFactories.Factories.Add(new JsonValueProviderFactory()); Pretty nice no?

P.S.: This Solution works so don't hesitate to ask more details.

like image 167
Demian Flavius Avatar answered Oct 05 '22 01:10

Demian Flavius


I came across this little hack, which resolves it nicely

window.addEventListener("submit", function (e) {     var form = e.target;     if (form.getAttribute("enctype") === "multipart/form-data") {         if (form.dataset.ajax) {             e.preventDefault();             e.stopImmediatePropagation();             var xhr = new XMLHttpRequest();             xhr.open(form.method, form.action);             xhr.onreadystatechange = function () {                 if (xhr.readyState == 4 && xhr.status == 200) {                     if (form.dataset.ajaxUpdate) {                         var updateTarget = document.querySelector(form.dataset.ajaxUpdate);                         if (updateTarget) {                             updateTarget.innerHTML = xhr.responseText;                         }                      }                 }             };             xhr.send(new FormData(form));         }     } }, true); 
like image 40
James 'Fluffy' Burton Avatar answered Oct 05 '22 01:10

James 'Fluffy' Burton