Reputation: 3313
Prologue: I have code that someone else wrote that should upload an image. It used to work but somehow I've broken it. By broken, I mean that when the model ultimately arrives at the controller, the image property is null. I can find an example of where it does work (creating a "scene"). When I compare the working example to the broken one (editing a "scene"), I can not find a reasonable difference between the two. I am, myself, a novice at MVC
Question:
Form Creation:
@using (Html.BeginForm("Edit", "Scene", null, FormMethod.Post, new { enctype = "multipart/form-data" }))
{
@Html.AntiForgeryToken()
@Html.HiddenFor(m => m.AccountTitlebar.Id)
@Html.HiddenFor(m => m.AccountTitlebar.Name)
@Html.HiddenFor(m => m.LocationName )
@Html.HiddenFor(m => m.CanDelete)
Image upload DIV: (within the form)
<div class="sixteen columns">
<label>@Html.DisplayNameFor(m => m.Image) (optional)</label>
@Html.TextBoxFor(m => m.Image, new { type = "file", accept = "image/*" })
</div>
The Model:
public class SceneCreateViewModel
{
public SceneCreateViewModel( )
{
ScheduleSet = new SceneScheduleSet( );
}
public AccountTitlebarModel AccountTitlebar { get; set; }
public string LocationName { get; set; }
public SceneNewOrUpdate Scene { get; set; }
public SceneScheduleSet ScheduleSet { get; set; }
[Display(Name="Image")]
public HttpPostedFileBase Image { get; set; }
public int ImageAction { get; set; }
public long? ImageId { get; set; }
public bool CanDelete { get; set; }
}
The Controller: (Once here, the image property of the model will be null)
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit( long id, SceneCreateViewModel model )
{
// CHECK IF MODEL IS VALID
if (!ModelState.IsValid)
{
return Json(new AjaxResult(ValidationErrorsText));
}
// ..... More Code below
The Rendered Form : (Relevant parts)
<form action="/Scene/Edit/10185" enctype="multipart/form-data" method="post"><input name="__RequestVerificationToken" type="hidden" value="{deleted}" /><input id="AccountTitlebar_Id" name="AccountTitlebar.Id" type="hidden" value="10" /><input id="AccountTitlebar_Name" name="AccountTitlebar.Name" type="hidden" value="{Deleted}" /><input id="LocationName" name="LocationName" type="hidden" value="{Deleted}" /><input id="CanDelete" name="CanDelete" type="hidden" value="True" /> <div class="row">
<div class="sixteen columns">
<h3 class="headline">{Deleted} - Front Deck - Edit Scene</h3><span class="line"></span><div class="clearfix"></div>
</div>
</div>
<div class="row nomargin">
<div class="sixteen columns">
</div>
</div>
<div class="row">
<div class="two columns">
<label for="Scene_OrdinalPosition">Scene</label>
1
<input id="Scene_OrdinalPosition" name="Scene.OrdinalPosition" type="hidden" value="1" />
</div>
<div class="six columns">
<label for="Scene_Name">Name</label>
<input class="form-control" id="Scene_Name" name="Scene.Name" type="text" value="Front Deck" />
</div>
<div class="six columns">
<label for="Scene_Description">Description</label>
<input class="form-control" id="Scene_Description" name="Scene.Description" type="text" value=" " />
</div>
</div>
<div class="row">
<div class="sixteen columns">
<label>Image (optional)</label>
<input accept="image/*" id="Image" name="Image" type="file" value="" />
</div>
</div>
A piece of JQuery that I found on the page.
$(function() {
$('form').submit(function() {
// SENDING THE MESSAGE
$('#SceneEdit_popup').text(' Processing, please wait....');
$('#SceneEdit_popup').bPopup();
// WAIT FOR GATEWAY TO RECEIVE MESSAGE
$.ajax({
type: this.method,
url: this.action,
data: $(this).serialize(),
success: function(data) {
// AFTER MESSAGE RECEVIED, SENDING TO DEVICES
var message = "Syncing devices, please wait...";
if (data.Success) {
$('#SceneEdit_popup').text(message);
} else {
message += "<p>" + data.Error + "</p>";
message += '<button type="button" ' +
'onclick="$(\'#SceneEdit_popup\').bPopup().close();">OK</button>';
$('#SceneEdit_popup').html(message);
}
},
error: function() {
// COMMUNICATION WAS LOST TO THE SERVER
var message = "<p>Internet connection was lost.</p>";
message += '<button type="button" ' +
'onclick="$(\'#SceneEdit_popup\').bPopup().close();">OK</button>';
$('#SceneEdit_popup').html(message);
}
});
return false;
});
Upvotes: 0
Views: 639
Reputation:
In order to upload files using ajax, you can use FormData
and set the appropriate ajax options (using form.serialize()
will not include file inputs)
$('form').submit(function() {
var formdata = new FormData($(this).get(0));
....
$.ajax({
type: this.method,
url: this.action,
data: formdata,
processData: false,
contentType: false,
success: function(data) {
....
Upvotes: 1