I've written some Javascript that allows me to have my MVC forms submit and reload in a specific Div instead of the whole page. This is working for most of the forms I use it in.
Now I'm trying to use this with a form that includes a File object. Originally this view worked like this:
@using (Html.BeginForm
(
"_submissionfiles",
"Project",
FormMethod.Post,
new { enctype = "multipart/form-data" }
)
)
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
@Html.HiddenFor(model => model.ProjectContentId)
<div class="form-group">
...
</div>
<div class="form-group">
@Html.LabelFor(model => model.ContentFile, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
<input type="file" id="ContentFile" name="ContentFile" value="ActionHandlerForForm" />
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default"/>
</div>
</div>
</div>
}
With a model and controller like this:
public class ProjectContentViewModel
{
public System.Guid ProjectContentId { get; set; }
public Guid? ProjectSubmissionId { get; set; }
//....
[Display(Name = "Content Type")]
public int ContentTypeId { get; set; }
[Display(Name = "Content")]
public HttpPostedFileBase ContentFile { get; set; }
}
[HttpPost]
[ValidateAntiForgeryToken]
public virtual ActionResult _submissionfiles(ProjectContentViewModel model)
{
if (!ModelState.IsValid) return View(model);
UploadedFile fileUploaded = null;
if (model.ContentFile.ContentLength > 0)
{
// handle file stuff
}
//...
db.SaveChanges();
AddMessage("Content submitted successfully.");
return View(model);
}
That worked, but would always return as the whole page. Now I've modified the Begin.Form to this:
@using (Html.BeginForm
(
"_submissionfiles",
"Project",
FormMethod.Post,
new { enctype = "multipart/form-data", id = "submissionFilesForm", @class = "ajaxformsubmit", data_target_div = "ProjectSubmissionPanel" }
)
)
{
//....
This would allow my javascript to handle the form submission, and return the results to the target_div. This works in other forms which do not have a file, but the problem here is when I get into the controller model.ContentFile
is Null. I suppose it's something to do with how I have javascript serializing the form.
Here's the javascript:
BindAjaxForm = function() {
$(".ajaxformsubmit").on("submit", function(e) {
e.preventDefault(); //This prevents the regular form submit
// I think this is where things need to get changed
AjaxAction(this.action, this.method, $(this).serialize(), $(this).attr("data-target-div"))
// ^^^^^^^^^^
return false;
});
};
AjaxAction = function (url, type, data, targetDivName) {
var targetDiv = $("#" + targetDivName);
$.ajax({
url: url,
type: type,
data: data, // or this?
success: function (result) {
// Load/Refresh a div if we have one.
if (typeof targetDiv != "undefined") {
targetDiv.html('');
targetDiv.html(result);
}
},
error: function (data) {
alert(data);
}
});
return false;
};
Is there a way in Javascript/Jquery to serialize the form with files intact?