I was trying to use an example mentioned here How to do a ASP.NET MVC Ajax form post with multipart/form-data?
But I keep getting "fail" error message box
Index.cshtml
<script src="~/Scripts/jquery-1.8.2.min.js"></script>
<script src="~/Scripts/jquery.unobtrusive-ajax.min.js"></script>
<h2>Files Upload</h2>
<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
},
error: function(jqXHR, textStatus, errorThrown) {
//do your own thing
alert("fail");
}
});
}); //end .submit()
});
</script>
<div id="uploadDiv">
@Html.Action("Files", "Home")
</div>
@using (Ajax.BeginForm("Files", "Home", new AjaxOptions { UpdateTargetId = "uploadDiv", HttpMethod = "Post" }, new { enctype = "multipart/form-data", @id="form0"}))
{
<div>
<div>Upload new file:
<input type="file" name="file" /></div>
<input type="submit" value="Save" />
</div>
}
<br />
Controller
public PartialViewResult Files(HttpPostedFileBase file)
{
IEnumerable<string> files;
if ((file != null) && (file.ContentLength > 0))
{
string fileName = file.FileName;
string saveLocation = @"D:\Files";
string fullFilePath = Path.Combine(saveLocation, fileName);
try
{
file.SaveAs(fullFilePath);
FileInfo fileInfo = new FileInfo(fullFilePath);
file.InputStream.Read(new byte[fileInfo.Length], 0, file.ContentLength);
}
catch (Exception e)
{
TempData["FileUpload"] = e.Message;
return PartialView();
}
files = Directory.GetFiles(@"D:\Files\");
return PartialView(files);
}
else
{
files = Directory.GetFiles(@"D:\Files\");
return PartialView(files);
}
}
Files.cshtml
@model IEnumerable<string>
@foreach (string f in Model)
{
<p>@f</p>
}
Global.asax
ValueProviderFactories.Factories.Add(new JsonValueProviderFactory());
That is complicated better use jquery forms plugin.
Here is the sample:
Html.BeginForm
Action Method
Progress Bar
Jquery & Form script
Update...
People who are getting issue of calling action method twice is due to Ajax.BeginForm, just convert it to Html.BeginForm(). For more clarification and to download sample code please refer at this blog.
The answer from
Ashwini Verma
is almost correct but it has a drawback, the form is submitted twice.This is caused by the use of
Ajax.BeginForm()
. UsingHtml.BeginForm()
will fix it.Here's an example:
You need html5 file handling and read file contents on client to get base64 encoded data.
On client you have to put:
So your code will fill hidden fields with file data (filename, type, size, base64 encoded contents). And on server side you put:
The code needs to be modified with your models and logic but it worked for me