假设您使用具有动态数量的表单元素的ASP.NET MVC创建表单。

例如,您需要为每个产品选中一个复选框,并且产品数量会逐日变化。

您如何处理发布回控制器的表单数据?您无法在操作方法上设置参数,因为您不知道将返回多少个表单值。

有帮助吗?

解决方案

只需为每个复选框指定一个唯一的名称值:

<input class="approveCheck" id="<%= "approveCheck" + recordId %>" 
 name="<%= "approveCheck" + recordId %>" type="checkbox" />

然后在提交后解析Action中的表单值列表:

foreach (var key in Request.Form.Keys)
    {
        string keyString = key.ToString();
        if (keyString.StartsWith("approveCheck", StringComparison.OrdinalIgnoreCase))
        {
            string recNum = keyString.Substring(12, keyString.Length - 12);

            string approvedKey = Request.Form["approveCheck" + recNum];
            bool approved = !String.IsNullOrEmpty(approvedKey);
            // ...

您不需要将表单值作为参数传递;你可以从Request.Form中获取它们。

另一个选项:编写模型绑定器以将列表更改为表单提交的自定义类型。

其他提示

Per Craig的答案......更安全。发布具有相同名称的多个表单元素有些怪癖。我想补充一点,将包含“集合”的逻辑包装起来是明智的。控件的方式与WebForms类似。 Web窗体预先添加容器控件的名称并添加索引。例如,在Repeater中,里面的表单元素将被命名(类似于)RepeaterName_Element1,RepeaterName_Element2。当你去获取元素时,你必须使用FindControl或类似的东西。

根据您使用的活页夹,这应该有效:

<%var i = 0;
  foreach (var product (IList<ProductSelection>)ViewData["products"]) {%>
      <%=Html.Hidden(string.Format("products[{0}].Id", i), product.Id)%>
      <%=Html.Checkbox(string.Format("products[{0}].Selected", i))%>
      <%=product.Name%><br/>
<%}%>

...这将导致HTML像这样(注意名称上的数组符号):

<input name="products[0].Id" type="hidden" value="123">
<input name="products[0].Selected" type="checkbox">
Widget
<input name="products[1].Id" type="hidden" value="987">
<input name="products[1].Selected" type="checkbox">
Gadget

...以及处理帖子的控制器方法:

public ActionResult SelectProducts(IList<ProductSelection> products)
{
     ...
}

在绑定时,products参数将包含两个ProductSelection实例。

有一点需要注意的是,我没有对复杂对象使用新的默认绑定。相反,我使用的是来自MvcContrib的NameValueDeserializer或CastleBind。他们都表现得这样。我猜测Beta中的绑定将以相同的方式工作。

根据您的数据,您可以输出'CheckboxList'(在较新版本中不再可能)并使用 string [] 参数,或者您可以设置多个表单并且只是修改动作。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top