如何从表单中获取 RadioButton 值?

How to get RadioButton values from form?

我有一个表单,可以为每条记录写出一个 Approve/Deny 单选按钮。我试图弄清楚如何使用 HttpPost 循环遍历每个单选按钮并确定是否选择了单选按钮,如果是,则选择了哪个。

通过一些研究,我发现有些人使用表单集合作为表单,在一个示例中,我发现用户在哪里使用表单 ViewModel(这是我通常所做的)。但是,当我尝试其中任何一个时,我都会空手而归。

这是我的表格。我正在将列表中的每条记录写到 table。我试过 Html.RadioButton 和 Html.RadioButtonFor 来创建它们。我还在 table 下方有一个评论文本框,有人可以在其中添加一些评论。这是视图的片段。

<tbody>
    @foreach (var item in Model.listPendingExceptions)
    {
        <tr>
            <td>@Html.RadioButton("rdo" + item.RID, "A")</td>
            <td>@Html.RadioButton("rdo" + item.RID, "D")</td>
            <td>@item.Shift_Date.ToShortDateString()</td>
        </tr>
    }
</tbody>

@Html.TextAreaFor(m => m.ExceptionComment, new { cols = 200, @rows = 4, @maxlength = "100", @class = "form-control", @placeholder = "100 character limitation", @autofocus = "autofocus" })

在我的 HttpPost 中,我尝试使用表单集合。但是,我发现的是查看 AllKeys 列表。当我查看 Post 时,AllKeys 中唯一的内容是评论的 TextBox 值。

当我在 HttpPost 中使用 ViewModel 时,我用来填充视图中 table 的异常列表为 NULL。我希望如此,因为我没有将列表存储在隐藏字段中。

我如何遍历每条记录,确定选择了哪个单选按钮,以及从“评论”文本框中获取文本?

更新 EditTemplate

我在视图中为 EditorTemplates 创建了文件夹结构。

我已经有一个包含异常列表的 ViewModel,但我确实将 SelectedApproval 从主 VM 移到了异常列表中。

public class ReportPendingExceptionsViewModel
    {
        public List<PendingException> listPendingExceptions { get; set; }

        public bool IsAdmin { get; set; }

        [Required(ErrorMessage = "*Required")]
        public string ExceptionComment { get; set; }
    } 

    public class PendingException
    {
        public int RID { get; set; }
        public DateTime Shift_Date { get; set; }
        public string Shift_Text { get; set; }
        public string Emp_Id { get; set; } 
        public string Emp_Name { get; set; }
        public string Last_Name { get; set; }
        public string First_Name { get; set; }
        public string Comment_Text { get; set; }
        public string SelectedApproval { get; set; }
    } 

然后我为 Table 行创建了一个 Razor 视图。

@model ProjectName.Models.ViewModels.PendingException

<tr>
    <td>@Html.RadioButtonFor(e=>e.SelectedApproval,"A")</td>
    <td>@Html.RadioButtonFor(e => e.SelectedApproval, "D")</td>
    <td>@Model.Shift_Date.ToShortDateString()</td>
    <td>@Model.Emp_Name</td>
    <td>@Model.Shift_Text</td>
    <td>@Model.Comment_Text</td>
    <td></td>
</tr>

然后我更新了主视图以使用 EditFor。

<thead>
    <tr>
        <th style="width:80px;">Approve</th>
        <th style="width:80px;">Deny</th>
        <th>Shift Date</th>
        <th>Employee</th>
        <th>Schedule</th>
        <th>Comments</th>
        <th></th>
    </tr>
</thead>
<tbody>
    @Html.EditorFor(f => f.listPendingExceptions)
</tbody>

然而,当我 运行 它时,我得到的只是 RID 值。所以,我一定是错过了什么。这是查看源代码的输出。

我是不是漏了一步?

使用 编辑器模板 可以很容易地做到这一点。

从为未决异常项创建视图模型开始

public class ExceptionVm
{
    public int Id { set; get; }
    public bool? IsApproved { set; get; }
    public DateTime ShiftDate { set; get; }
} 

并且在您的主视图模型中,您将添加一个集合 属性 List<ExceptionVm>.

public class MyViewModel
{
   public string Comment { set;get;}
   public List<ExceptionVm> PendingExceptions { set;get;}
   public MyViewModel()
   {
     PendingExceptions = new List<ExceptionVm>();
   }
}

然后在 GET 操作中初始化视图模型对象,加载 PendingExceptions 属性

public ActionResult Create()
{
    var vm = new MyViewModel();
    vm.ExceptionVms = new List<ExceptionVm>()
    {
        new ExceptionVm() {Id = 1, ShiftDate = DateTime.Now.AddDays(-3)},
        new ExceptionVm() {Id = 2, ShiftDate = DateTime.Now.AddDays(-2)},
        new ExceptionVm() {Id = 3, ShiftDate = DateTime.Now.AddDays(-1)}
    };
    return View(vm);
}

现在,让我们创建一个编辑器模板。在 ~/Views/YourControllerName/~/Views/Shared/ 下创建一个名为 EditorTemplates 的新目录,并在其下添加一个新的 razor 视图。将文件命名为与我们的视图模型相同的名称 class、ExceptionVm.cshtml

现在将以下代码添加到编辑器模板视图中。这基本上呈现了 2 个单选按钮和日期

@model ExceptionVm
<tr>
    <td>@Html.RadioButtonFor(b=>b.IsApproved, true)</td>
    <td>@Html.RadioButtonFor(b => b.IsApproved, false) </td>
    <td> @Model.ShiftDate   @Html.HiddenFor(x=>x.Id)    </td>
</tr>

现在转到您的主视图,它是我们的 MyViewModel class 的强类型,然后调用 Html.EditorFor 辅助方法并将 PendingExceptions 集合 属性 传递给那

@model MyViewModel
@using(Html.BeginForm())
{
      <table class="table">
        <tbody>
            @Html.EditorFor(f => f.PendingExceptions)
        </tbody>
    </table>
    @Html.TextBoxFor(f => f.Comment)
   <input type="Submit" value="Submit" class="btn btn-default" />
}

调用 EditorFor 将为 PendingExceptions 集合中的每个项目呈现一个 table 行。当您提交表单时,您可以使用相同的 MyViewModel class 作为参数并检查 PendingExceptions 属性,遍历每个项目并查看它是 true 还是 falsenull(如果他们没有选择任何东西)

[HttpPost]
public ActionResult Create(MyViewModel model)
{
  // check model.PendingExceptions collection and each items IsApproved prop value
 // to do  : return something
}

如果您不想允许空选择,请将 IsApproved 属性 类型从 bool? 更改为 bool

    public class ExceptionModel
    {
        public int Id { set; get; }
        public bool IsApproved { set; get; }
        public DateTime ShiftDate { set; get; }
    } 

    public class MainModel  
    {
        public string Comment { set;get;}
        public List<ExceptionModel> lst_Exception { set;get;}
    } 

   //this is get request action method
    public ActionResult Create()
    {
        MainModel model = new MainModel();
        model.lst_Exception = new List<ExceptionModel>()
        {
            new ExceptionModel() {Id = 1,IsApproved = false, ShiftDate = DateTime.Now},
            new ExceptionModel() {Id = 2,IsApproved = false, ShiftDate = DateTime.Now},
            new ExceptionModel() {Id = 3,IsApproved = false, ShiftDate = DateTime.Now}
        };

        return View(model);
    }

   //this is view for action method
    @model MainModel
    @using(Html.BeginForm())
    {
      <table>
        <thead>
            <tr>
              <th>Approve</th>
              <th>Deny</th>
              <th>Shift Date</th>
            </tr>
        </thead>
        <tbody>
          @for (var item = 0; item < Model.lst_Exception.Count(); item++)
             {
                <tr>
                  <td>@Html.RadioButtonFor(model=>model.lst_Exception[item].IsApproved, "Approve")</td>
                  <td>@Html.RadioButtonFor(model=>model.lst_Exception[item].IsApproved, "Deny")</td>
                  <td><span>@Model.lst_Exception[item].ShiftDate</span>
               @Html.HiddenFor(model => model.lst_Exception[item].ShiftDate})
                  </td>
                </tr>
             }
        </tbody> 
      </table>
   @Html.TextBoxFor(model=>model.Comment)
   <input type="Submit" value="Submit" />
    }

//this is Post action method
[HttpPost]
public ActionResult Create(MainModel model)
{
  //here you can loop through model.lst_Exception to get the select values 
  //from the view 
}