【问题标题】:How to use a Html.DropDownList in a strongly-typed view for a model containing a nullable enum property?如何在强类型视图中为包含可为空枚举属性的模型使用 Html.DropDownList?
【发布时间】:2011-02-05 03:27:45
【问题描述】:

我有一个模型类如下:

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; }
    }
}

Edit 操作会:

namespace MvcApplication1.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Edit()
        {
            var Person = new Person { Id = 1, Name = "Someone", Sex = Sex.Male };
            return View(Person);
        }
    }
}

问题 1

如何标记Edit 视图,以便有一个包含 3 个选项的下拉控件:“--Select--”、“Female”和“Male”。对于传递给视图的Person,必须选择“男性”。

问题 2

如何组成Create 视图并让下拉控件默认选择“--Select--”。

这是Create 操作:

 public ActionResult Create()
 {
       var Person = new Person();
       return View(Person);
 }

【问题讨论】:

    标签: asp.net-mvc


    【解决方案1】:

    有一个good answer already on how to convert an Enum into a SelectList,但我会内联重用该代码来简单地回答。

    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);
    }
    

    现在是 Edit.cshtml 视图:

    @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>
    

    现在将表单发布到的控制操作:

    [HttpPost]
    public ActionResult Edit(Person person)
    {
        var newName = person.Name;
        var newSex = person.Sex;
    
        return RedirectToAction("index", "home");
    }
    

    现在在调试模式下运行项目,并在 post-to Edit 操作中的 return RedirectToAction("index", "home"); 行中断。看看如何在视图中更改表单值,然后在 post-to 操作中执行您需要执行的操作?除了使用 ViewData 传递列表之外,还有其他选项,但它们使示例复杂化并且数量众多。

    Create 操作如下所示:

    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);
    }
    

    默认选择列表项将是第一个,因此它将显示“--Select--”作为默认选项。

    【讨论】:

    • 首先,非常感谢。我可以将Edit.cshtml 升级为Person.cshtml 吗?当我将Person.cshtml 用于Create 操作时,下拉菜单是否默认选择“--Select--”?
    • 我现在将编辑并添加 --Select-- 部分。按照惯例,编辑操作将使用编辑视图。您可以强制它使用不同的视图,如下所示:return View("Person", Person)。但是,让 Edit 和 Create 视图共享表单的公共 EditPerson 部分更有意义。这样,您仍然可以在页面上说“编辑”或“创建”,并获得有关编辑或创建的详细信息,但共享表单工作。
    • 要共享表单的公共部分,创建一个名为 EditPerson 的新部分视图,然后在编辑和创建视图中放置表单的位置 @Html.RenderPartial("EditPerson", Model) 这将传递视图模型到局部。 EditPerson 部分的内容可以是&lt;h2&gt;Edit&lt;/h2&gt; 下面的所有内容。
    • "--Select--" 可以传递给Html.DropDownListFor 的第三个参数。但我不知道哪种方式更好,你的还是我的?
    • 最后一个细节:有些人喜欢创建与域模型分开的视图模型。这样他们就可以将选择列表放在视图模型中,避免通过 ViewData[...] 传递它。有利有弊,但值得了解这些选项。使用 ViewData 显示示例当然更简单,这就是我在这里使用它的原因。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-10
    • 1970-01-01
    • 2015-05-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-07
    相关资源
    最近更新 更多