How to use a Html.DropDownList in a strongly-typed view for a model containing a nullable enum property?
I have a model class as follows:
namespace MvcApplication1.Models
{
public enum Sex { Male, Female };
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
[Required(ErrorMessage="Please select either Female or Male.")]
public Sex? Sex { get; set; }
}
}
The Edit
action does :
namespace MvcApplication1.Controllers
{
public class HomeController : Controller
{
public ActionResult Edit()
{
var Person = new Person { Id = 1, Name = "Someone", Sex = Sex.Male };
return View(Person);
}
}
}
Question 1
How to mark up the Edit
view such that there is a dropdown control containing 3 options: "--Select--", "Female", and "Male". For the Person
passed to the view, "Male" must be selected.
Question 2
How to make up the Create
view and leave the dropdown control selec开发者_如何学Pythonting "--Select--" by default.
Here is the Create
action:
public ActionResult Create()
{
var Person = new Person();
return View(Person);
}
There is a good answer already on how to convert an Enum into a SelectList but I'll reuse that code inline to simply the answer.
public ActionResult Edit()
{
var Person = new Person { Id = 1, Name = "Someone", Sex = Sex.Male };
List<object> values = new List<object>();
values.Add(new { ID = "choose", Name = "--Select--" });
values.AddRange(from Sex sex in Enum.GetValues(typeof(Sex))
select new { ID = sex, Name = sex.ToString() });
ViewData["sexes"] = new SelectList(values, "Id", "Name", Person.Sex);
return View(Person);
}
Now the Edit.cshtml view:
@model Test.Models.Person
@{
ViewBag.Title = "Edit";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Edit</h2>
<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
@using (Html.BeginForm()) {
@Html.ValidationSummary(true)
<fieldset>
<legend>Person</legend>
@Html.HiddenFor(model => model.Id)
<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.Sex)
</div>
<div class="editor-field">
@Html.DropDownListFor(model => model.Sex, (SelectList)ViewData["sexes"])
@Html.ValidationMessageFor(model => model.Sex)
</div>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
Now the control action to post the form to:
[HttpPost]
public ActionResult Edit(Person person)
{
var newName = person.Name;
var newSex = person.Sex;
return RedirectToAction("index", "home");
}
Now run the project in debug mode with a break on the return RedirectToAction("index", "home");
line in the post-to Edit action. See how you can change form values in the view and then do what you need to do in the posted-to action? There are other options than using ViewData to pass the list but they complicate the example and are plentiful.
The Create
action would look like this:
public ActionResult Create()
{
Person person = new Person();
List<object> values = new List<object>();
values.Add(new { ID = "choose", Name = "--Select--" });
values.AddRange(from Sex sex in Enum.GetValues(typeof(Sex))
select new { ID = sex, Name = sex.ToString() });
ViewData["sexes"] = new SelectList(values, "Id", "Name");
return View(person);
}
The default select list item will be the first one so it would show "--Select--" as the default choice.
精彩评论