MVC4枚举和单选按钮列表

时间:2013-08-30 21:59:57

标签: asp.net-mvc asp.net-mvc-4

我已经看到了一些线程,但似乎没有一个适用于MVC4,因为RadioButtonFor html扩展方法/帮助器不存在。

说我有一个枚举列表 - 即航空公司:

public enum Airlines
{
   Unknown = 0,
   BritishAirways = 1,
   VirginAtlantic = 2,
   AirFrance = 3
}

如何将其绑定到我视图上的单选按钮列表并能够检索所选项目? 如果没有选择,可以说“选择一个项目”怎么样?

5 个答案:

答案 0 :(得分:43)

您可以为将呈现单选按钮列表的枚举Airlines创建自定义编辑器模板。在您的模型中,您将拥有Airlines类型的属性,并使用Required属性标记此属性并设置ErrorMessage = "select one item"。如果需要,请不要忘记在客户端验证中包含jQuery验证,通常只需在Layout或View上添加@Scripts.Render("~/bundles/jqueryval")。如果您不使用jQuery验证,则需要在模型上使该属性为空,因为枚举默认设置为第一个值,因此MVC不会将其视为无效。请记住,如果将属性更改为可空,则还需要将编辑器模板的模型类型更改为可为空。

<强>更新

要启用编辑器模板为任何枚举呈现单选按钮列表,请将模板更改为以下内容:

@model Enum
@foreach (var value in Enum.GetValues(Model.GetType()))
{
    @Html.RadioButtonFor(m => m, value)
    @Html.Label(value.ToString())
}

<强> ORIGINAL

编辑模板 Airlines.cshtml ,位于 Views \ Shared \ EditorTemplates 目录中:

@model MvcTest.Models.Airlines
@foreach (var value in Enum.GetValues(typeof(MvcTest.Models.Airlines)))
{
    @Html.RadioButtonFor(m => m, value)
    @Html.Label(value.ToString())
}

模特:

public class TestModel
{
    [Required(ErrorMessage = "select one item")]
    public Airlines Airline { get; set; }
}

行动方法:

public class HomeController : Controller
{
    [HttpGet]
    public ActionResult Index()
    {
        return View(new TestModel());
    }

    [HttpPost]
    public ActionResult Index(TestModel model)
    {
        if (ModelState.IsValid)
        {
            return RedirectToAction("Index");
        }

        return View(model);
    }
}

观点:

@model MvcTest.Models.TestModel
@{
    ViewBag.Title = "Index";
    Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Index</h2>
@using (Html.BeginForm())
{
    @Html.EditorFor(m => m.Airline)
    <input type="submit" value="Submit" />
    @Html.ValidationSummary(false)
}

答案 1 :(得分:30)

我建议对其他答案采用类似的方法,但使用以下编辑器模板; EnumRadioButtonList.cshtml ,位于 Views \ Shared \ EditorTemplates 目录中:

@model Enum
@foreach (var value in Enum.GetValues(Model.GetType()))
{
    var id = TagBuilder.CreateSanitizedId(string.Format(
        "{0}_{1}_{2}", ViewData.TemplateInfo.HtmlFieldPrefix, Model.GetType(), value));
    <div>
        @Html.RadioButton(string.Empty, value, value.Equals(Model), new { id })
        @Html.Label(value.ToString(), new { @for = id })
    </div>
}

每个单选按钮的HTML id必须是唯一的。因此,上面的代码通过使用idViewData.TemplateInfo.HtmlFieldPrefix添加了绑定属性的名称前缀。如果模型包含使用此枚举的多个属性,并且每个属性都使用了此编辑器模板,则可以确保唯一id

每个单选按钮的随附label将正确设置其for属性。 这意味着用户可以通过单击标签文本来选择一个单选按钮,这是一个比单选按钮本身更大更好的点击目标。

对于MVC模型绑定,单选按钮的HTML name属性值都设置为EditorFor调用中指定的属性(在此方案中为Airline

使用它:

@Html.EditorFor(m => m.Airline, "EnumRadioButtonList")

答案 2 :(得分:16)

RadioButtonFor是什么意思不存在?我使用MVC4并在我的代码中使用它。对于列表,您可以将多个设置为相同的名称

@Html.RadioButtonFor(x => x.Airlines, Airlines.Unknown)
@Html.RadioButtonFor(x => x.Airlines, Airlines.BritishAirways)
@Html.RadioButtonFor(x => x.Airlines, Airlines.VirginAtlantic)
@Html.RadioButtonFor(x => x.Airlines, Airlines.AirFrance)

这些将与模型绑定,因此在回发后您将看到航空公司设置为所选项目,并且在加载页面时将选择匹配的单选按钮。

答案 3 :(得分:2)

我将asymptoticfault的最高评分答案提高了一点,以反映所选的值。 将此作为EnumRadioButton.cshtml保存到您的共享视图EditorTemplates文件夹:

@model Enum
@foreach (var value in Enum.GetValues(Model.GetType()))
{
    if (Equals(Model, value))
    {
        @Html.RadioButtonFor(m => m, value, new {@checked = "checked"})
    }
    else
    {
        @Html.RadioButtonFor(m => m, value)
    }

    @Html.Label(value.ToString())
}

用法:

@Html.EditorFor(item => Model.MyEnumType, "EnumRadioButton")

答案 4 :(得分:2)

我能够将其他答案中的一些方法与一些附加功能结合起来:

EnumRadioButtonList.cshtml

@model Enum
@foreach (var item in EnumHelper.GetSelectList(Model.GetType()))
{
    <div class="radio">
        <label>
            @Html.RadioButton(string.Empty, item.Value, Model.Equals(Enum.Parse(Model.GetType(), item.Value)))
            @item.Text
        </label>
    </div>
}

这使用EnumHelper.GetSelectList()作为一种黑客攻击,以便您可以使用枚举成员的显示属性:

public enum TestEnum
{
    First,
    [Display(Name = "Second Member")]
    Second,
    Third
}

用法:

@Html.EditorFor(m => m.TestEnumProperty, "EnumRadioButtonList")

收率:

Image

我也使用Bootstrap单选按钮样式和内联版本的单独助手:

EnumRadioButtonListInline.cshtml

@model Enum
@foreach (var item in EnumHelper.GetSelectList(Model.GetType()))
{
    <label class="radio-inline">
        @Html.RadioButton(string.Empty, item.Value, Model.Equals(Enum.Parse(Model.GetType(), item.Value)))
        @item.Text
    </label>
}