C#MVC:从View中动态地向ViewModel添加对象

时间:2014-05-21 16:20:56

标签: c# asp.net-mvc dynamic binding model

我有以下视图(见下文) - 这个想法是它会在表格中显示任何现有的品牌商品,但也让用户能够添加新的品牌商品(并上传相关的品牌文件)。视觉上它的工作方式应该如此。用户单击该按钮以动态添加附加空表的新表行。

我遇到的问题是,表中新添加的行没有被绑定到ViewModel,所以当我点击提交并调试到我的Action时,只有一行(或者有很多行是预先存在)绑定到ViewModel。我也不确定如何从formValues变量获取此信息,因为将每行检索为不可行:

BrandItems[1].Identifier, BrandItems[2].Identifier

因为我永远不会知道有多少存在。

我使用此方法的另一个问题是将文件上传绑定到模型。

非常感谢任何帮助。任何问题或需要更多信息只是问。

这是我的观点:

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Main.Master" 
Inherits="System.Web.Mvc.ViewPage<MyProject.Web.Models.BrandViewModel>" %>

<%@ Import Namespace="MyProject.Extensions" %>

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

    <% Html.BeginForm("EditBrandItems", "Brands"); %>
    <table class="normal" border="1px" cellpadding="2px" style="border-collapse: collapse; width: 530px;">
        <tr>
            <th style="text-align: left;">
                Delete
            </th>
            <th style="text-align: left;">
                Type
            </th>
            <th style="text-align: left;">
                Identifier
            </th>
            <th>
                File Upload
            </th>
        </tr>
        <% for (int i = 0; i < Model.BrandItems.Count; i++) %>
        <% { %>
        <% var tb = Model.BrandItems[i]; %>
        <tr class="BrandItems-editor">
            <td style="text-align: center;">
                <%: Html.HiddenFor(m => m.BrandItems[i].BrandItemID) %>
                <%: Html.HiddenFor(m => m.BrandItems[i].BrandID) %>
                <%: Html.HiddenFor(m => m.BrandItems[i].FileName) %>
                <%: Html.HiddenFor(m => m.BrandItems[i].BrandItemType.Name) %>

                <%: Html.EditorFor(m => m.BrandItems[i].Deleted) %>
            </td>
            <td style="text-align: center;">
                <%: tb.BrandItemType.Name %>
            </td>
            <td style="text-align: center;">
                <%: Html.EditorFor(m => m.BrandItems[i].Identifier) %>
            </td>
            <td>
                <input name="ASSET_<%: Model.BrandItems[i].BrandItemID %>" type="file" id="ASSET_<%: Model.BrandItems[i].BrandItemID %>" />
            </td>
        </tr>

        <% if (i == 0) { %>
        <tr class="BrandItems-editor-template" style="display:none">
            <td style="text-align: center;">
                <%: Html.EditorFor(m => m.BrandItems[i].Deleted) %>
            </td>
            <td style="text-align: center;">
                <%: Html.EditorFor(m => m.BrandItems[i].BrandItemType.Name) %>
            </td>
            <td style="text-align: center;">
                <%: Html.EditorFor(m => m.BrandItems[i].Identifier) %>
            </td>
            <td>
               <input name="NEWASSET_<%: Model.BrandItems[i].BrandID %>" type="file" id="NEWASSET_<%: Model.BrandItems[i].BrandID %>" />
            </td>
        </tr>
        <% } %>
     <% } %>

    </table>
    <br />
    <input type="button" class="add-button" name="add" value="Add" />
    <% Html.RenderPartial("UpdateButtons"); %>
    <% Html.EndForm(); %>
</asp:Content>

<asp:Content ID="Content3" ContentPlaceHolderID="Header" runat="server">
    <script type="text/javascript">
        $(document).ready(function () {
            var count = 2;
            $('.add-button').click(function () {
                count++;
                var template = $('.BrandItems-editor-template').clone()
                template.find('input[type=text]').val('');
                $.each(template.find('input[type=text]'), function () {
                    var name = $(this).attr('name');
                    name = name.replace('0', count - 1);
                    $(this).attr('name', name);
                });

                $('.normal').append(template);
                template.removeClass('BrandItems-editor-template').addClass('BrandItems-editor').show();
            })
        });
 </script>
</asp:Content>

这是我的控制器中的操作方法:

[HttpPost]
[ValidateInput(false)]
public virtual ActionResult EditBrandItems(BrandViewModel model, FormCollection formValues)
{
    //DO SOMETHING WITH DATA
    return View(model);
}

HEre是BrandViewModel - (BrandItems是此模型中的列表)

    public class BrandViewModel
    {
        public BrandViewModel()
        {
            Brand = new Brand();
            BrandItems = new List<Data.BrandItem>();
        }

        public Data.Brand Brand { get; set; }
        public List<Data.Brand> BrandItems { get; set; }
    }

1 个答案:

答案 0 :(得分:1)

将BrandViewModel更改为List&lt; BrandViewModel&gt;模型

 [HttpPost] 
    [ValidateInput(false)]
    public virtual ActionResult EditBrandItems(List < BrandViewModel > model, FormCollection formValues)
    {
        //DO SOMETHING WITH DATA
        return View(model);
    }

我认为你应该创建两个按钮,它们将添加新行和第二个提交。检查生成的页面的html并查看最后一项(for(int i = 0; i&lt; Model.BrandItems.Count; i ++))。您附加在表格中的下一个项目应使用下一个ID生成。如果没有帮助你应该在mvc中寻找自定义绑定器。 祝你好运