【问题标题】:pass enum to html.radiobuttonfor MVC3将枚举传递给 html.radiobuttonfor MVC3
【发布时间】:2011-08-03 00:32:54
【问题描述】:

我有一个名为 ActionStatus 的枚举,它有 2 个可能的值 open=0 和 closed = 1

public enum ActionStatus
{
    Open,
    Closed
}

我想在我的编辑中构建单选按钮组并创建使用枚举来填充单选按钮的视图,其中 a) 创建视图中的默认值和 b) 编辑视图中当前选择的选项。

我需要一个扩展方法吗?有人已经创建了吗?

编辑:在下面达林斯的回答之后,这是我的模型课

namespace Actioner.Models
{
[MetadataType(typeof(MeetingActionValidation))]
public class MeetingAction
{
    [Key]
    public int MeetingActionId              { get; set; }       

    [Required]
    [Display(Name = "Description")]
    public string Description  { get; set; }

    [Required]
    [Display(Name = "Review Date")]
    public DateTime ReviewDate       { get ;set; }

    public int Status{ get; set; }

    [ScaffoldColumn(false)]
    public int MeetingId             { get; set; }


    //public virtual Meeting Meeting { get; set; }

    //public virtual ICollection<User> Users { get; set; }
    public virtual ICollection<ActionUpdate> ActionUpdates { get; set; }

    public MeetingActionStatus ActionStatus { get; set; }

}

public enum MeetingActionStatus 
{
    Open,
    Closed
}

这是我的观点

@model Actioner.Models.MeetingAction
@using Actioner.Helpers


<div class="editor-label">
@Html.LabelFor(model => model.Description)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Description)
@Html.ValidationMessageFor(model => model.Description)
</div>

<div class="editor-label">
@Html.LabelFor(model => model.ReviewDate)
</div>
 <div class="editor-field">
@Html.EditorFor(model => model.ReviewDate)
@Html.ValidationMessageFor(model => model.ReviewDate)
</div>

<div class="editor-label">
@Html.LabelFor(model => model.Status)
</div>
<div class="editor-field">

 @Html.RadioButtonForEnum(x => x.ActionStatus)

</div>

这是我的创建控制器操作

public virtual ActionResult Create(int id)
    {

        var meetingAction = new MeetingAction
        {
            MeetingId = id,
            ReviewDate = DateTime.Now.AddDays(7)
        };

        ViewBag.Title = "Create Action"; 

        return View(meetingAction);
    } 

枚举在视图中显示正常,但当前选择的选项没有持久化到数据库中

【问题讨论】:

  • 有没有办法从资源文件中检索打开和关闭值?例如:[Display(Name = "Open", ResourceType = typeof(Resources.Global), Order = 0)] 打开。

标签: asp.net-mvc asp.net-mvc-3 enums


【解决方案1】:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Html;

namespace YourNamespace
{
    public static class HtmlExtensions
    {
        public static MvcHtmlString RadioButtonForEnum<TModel, TProperty>(
            this HtmlHelper<TModel> htmlHelper, 
            Expression<Func<TModel, TProperty>> expression
        )
        {
            var metaData = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
            var names = Enum.GetNames(metaData.ModelType);
            var sb = new StringBuilder();
            foreach (var name in names)
            {
                var id = string.Format(
                    "{0}_{1}_{2}", 
                    htmlHelper.ViewData.TemplateInfo.HtmlFieldPrefix, 
                    metaData.PropertyName, 
                    name
                );

                var radio = htmlHelper.RadioButtonFor(expression, name, new { id = id }).ToHtmlString();
                sb.AppendFormat(
                    "<label for=\"{0}\">{1}</label> {2}", 
                    id, 
                    HttpUtility.HtmlEncode(name), 
                    radio
                );
            }
            return MvcHtmlString.Create(sb.ToString());
        }
    }
}    

您还可以为此帮助方法强制使用generic constraint to an enum type

然后:

型号:

public enum ActionStatus
{
    Open,
    Closed
}

public class MyViewModel
{
    public ActionStatus Status { get; set; }
}

控制器:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View(new MyViewModel
        {
            Status = ActionStatus.Closed
        });
    }

    [HttpPost]
    public ActionResult Index(MyViewModel model)
    {
        return View(model);
    }
}

查看:

@model MyViewModel
@using (Html.BeginForm())
{
    @Html.RadioButtonForEnum(x => x.Status)
    <input type="submit" value="OK" />
}

【讨论】:

  • 为什么要使用字符串生成器?只是为了便于连接和格式化?这似乎是一种非常非 MVC 的做事方式。
  • Jon Skeet 关于对枚举类型实施通用约束的博客文章的链接不再有效。
  • 花了几分钟找出正确的 using 语句用于 HtmlExtensions 代码,因此我编辑了您的答案以包含它们。希望你不要介意。
【解决方案2】:

只需为单选按钮添加标签

    public static class HtmlExtensions
{
    public static MvcHtmlString RadioButtonForEnum<TModel, TProperty>(
        this HtmlHelper<TModel> htmlHelper,
        Expression<Func<TModel, TProperty>> expression
    )
    {
        var metaData = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);

        var names = Enum.GetNames(metaData.ModelType);
        var sb = new StringBuilder();
        foreach (var name in names)
        {

            var description = name;

            var memInfo = metaData.ModelType.GetMember(name);
            if (memInfo != null)
            {
                var attributes = memInfo[0].GetCustomAttributes(typeof(DisplayAttribute), false);
                if (attributes != null && attributes.Length > 0 )
                    description = ((DisplayAttribute)attributes[0]).Name;
            }
            var id = string.Format(
                "{0}_{1}_{2}",
                htmlHelper.ViewData.TemplateInfo.HtmlFieldPrefix,
                metaData.PropertyName,
                name
            );

            var radio = htmlHelper.RadioButtonFor(expression, name, new { id = id }).ToHtmlString();
            sb.AppendFormat(
                "<label for=\"{0}\">{1}</label> {2}",
                id,
                HttpUtility.HtmlEncode(description),
                radio
            );
        }
        return MvcHtmlString.Create(sb.ToString());
    }
}

和模型:

    public enum MeetingActionStatus                   
{

    [Display(Name = "Open meeting")]
    Open,

    [Display(Name = "Closed meeting")]
    Closed             
}          

【讨论】:

  • 在模型上和 Display 属性的扩展中使用 非常有用,因为枚举描述通常无法以原始格式实际显示。
  • 我收到一个错误 - “System.Web.Mvc.HtmlHelper”不包含“RadioButtonFor”的定义,并且没有扩展方法“RadioButtonFor”接受“System”类型的第一个参数.Web.Mvc.HtmlHelper'
  • 尝试“使用 System.Web.Mvc.Html;”
猜你喜欢
  • 2015-01-07
  • 1970-01-01
  • 2011-05-10
  • 1970-01-01
  • 1970-01-01
  • 2023-03-30
  • 2017-02-07
  • 2012-01-14
  • 1970-01-01
相关资源
最近更新 更多