I am making a View that has a DropDown. The view is supplied with a CategoryModel that looks like this:
public class CategoryModel
{
[Required]
[Display(Name = "Categories")]
public List<Category> Categories { get; set; }
[Required]
[GreaterThan(ExceedValue = 0, ErrorMessage = "Please select a category.")]
[Display(Name = "SelectedCategoryId")]
public int SelectedCategoryId { get; set; }
}
The List of Categories is used within the view to populate the DropDown by first taking the categories and put them in a SelectList, like this:
@model RatingMVC3.Models.CategoryModel
@{
Layout = "~/Views/Shared/_MainLayout.cshtml";
ViewBag.Title = "Upload";
}
<h2>Upload</h2>
@using (Html.BeginForm("Upload", "Upload", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<input type="file" name="file" />
<input type="submit" value="OK" />
@Html.DropDownListFor(m => m.SelectedCategoryId, new SelectList(Model.Categories, "Id", "Description"), "-- Select Category --");
@Html.ValidationMessageFor(m => m.SelectedCategoryId);
@Html.HiddenFor(m => m.Categories);
}
When this form is submitted, and the model is returned to the Controller, I can see that the model comes back into the Controller, but it contains an empty List instead of the List of Categories that was there in the View. (The SelectedCategoryId is there as expected). Here is the ActionResult method in the Controller:
[HttpPost]
[Authorize]
public ActionResult Upload(HttpPostedFileBase file, CategoryModel model)
{
if (ModelState.IsValid)
{
if (file != null && file.ContentLength > 0)
{
var FileExtension = Path.GetExtension(file.FileName);
string Path1 = null;
string FileName = null;
do
{
var randomName = Path.GetRandomFileName();
FileName = Path.ChangeExtension(randomName, FileExtension);
Path1 = Path.Combine(Server.MapPath("~/Images"), FileName);
} while (System.IO.File.Exists(Path1));
file.SaveAs(Path1);
if (UploadService.SaveImage(FileName, System.Web.HttpContext.Current.User.Identity.Name, model.SelectedCategoryId))
{
return RedirectToAction("Uploaded", "Upload");
}
}
return RedirectToAction("Index", "Home");
}
return View(model);
}
The empty list is a problem for me, because as you can see, if the ModelState is not valid, the view will be returned with the same model again, and needs to be populated with categories.
I hope someone can answer this 😉 I will gladly specify more information if needed, Thanks in advance
During a POST operation, the entire select list (drop down) is not returned to the controller/form action, only the selected value from that list. If you have to re-render the view because of bad validation, you can either a) Do an AJAX submit instead of a full POST for validation reasons or b) recreate your list and send it back with the View on Error. Option b) can be implemented as such:
I guess if you wanted, you could store the list of items as a hidden input on your page, but that just looks ugly, adds to the amount of data being sent to and from the web page and gosh darn it, just sounds a heck of a lot like ViewState (shrudders).