【问题标题】:How do you handle the output of a dynamically generated form in ASP.NET MVC?如何处理 ASP.NET MVC 中动态生成的表单的输出?
【发布时间】:2008-10-21 19:24:57
【问题描述】:

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

例如,您需要为每个产品设置一个复选框,并且产品的数量每天都在变化。

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

【问题讨论】:

    标签: asp.net-mvc forms post


    【解决方案1】:

    只需给每个复选框一个唯一的名称值:

    <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 中获取它们。

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

    【讨论】:

      【解决方案2】:

      根据克雷格的回答.. 更安全。发布具有相同名称的多个表单元素有一些怪癖。我要补充一点,以类似于 WebForms 的方式包装使控件“集合”的逻辑是明智的。 Web 窗体预先添加容器控件的名称并添加索引。例如,在中继器中,内部的表单元素将被命名(类似于)RepeaterName_Element1、RepeaterName_Element2。当你去取出元素时,你必须使用 FindControl 或类似的东西。

      【讨论】:

        【解决方案3】:

        根据您使用的活页夹,这应该可以工作:

        <%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 版中的绑定会以同样的方式工作。

        【讨论】:

          【解决方案4】:

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2010-10-21
            • 1970-01-01
            • 1970-01-01
            • 2010-10-29
            • 1970-01-01
            • 1970-01-01
            • 2018-12-16
            • 1970-01-01
            相关资源
            最近更新 更多