Posted by ben
20. April 2011 08:23
A while ago I posted how you can upload multiple files in ASP.NET MVC. You can see that post here.
Someone left a comment on that post asking how they might POST both data and files to a controller action (the example was to create a product and upload the product images).
Fortunately ASP.NET MVC makes this pretty trivial since the built in model binders can handle complex view models too.
So first let’s create our viewmodel. We will have properties for Name, Price and Images:
public class ProductViewModel {
public string Name { get; set; }
public decimal Price { get; set; }
public IEnumerable Images { get; set; }
}
Then we create our controller GET and POST actions:
public ActionResult NewProduct()
{
return View();
}
[HttpPost]
public ActionResult NewProduct(ProductViewModel viewModel)
{
// save product
// var product = new Product { Name = viewModel.Name, Price = viewModel.Price });
// repo.Save(product);
// now do something with the files
foreach (var file in viewModel.Images)
{
if (file.ContentLength > 0)
{
var fileName = Path.GetFileName(file.FileName);
var path = Path.Combine(Server.MapPath("~/App_Data/uploads"), fileName);
file.SaveAs(path);
}
}
return RedirectToAction("Index");
}
Our POST action has a parameter of type ProductViewModel. The modelbinder will handle wiring up the posted vales to our view model class.
Finally our view:
<form method="post" action="@Url.Action("NewProduct")" enctype="multipart/form-data">
@Html.ValidationSummary(true)
<fieldset>
<legend>ProductViewModel</legend>
<div class="editor-label">
@Html.LabelFor(model => model.Name)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Name)
@Html.ValidationMessageFor(model => model.Name)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Price)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Price)
@Html.ValidationMessageFor(model => model.Price)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Images)
</div>
<div class="editor-field">
<input type="file" name="Images" />
<input type="file" name="Images" />
<input type="file" name="Images" />
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
</form>
This time I haven’t bothered using the multiple file upload helper. Instead I’ve placed three file inputs all with the same name. Note that the name of the file inputs should correspond to the name of the IEnumerable<HttpPostedFileBase> property on your view model.

That’s really all there is to it.