• MVC批量添加,增加一条记录的同时添加N条集合属性所对应的个体


    类别中包含一个产品的集合属性,如何向数据库添加一条类别记录的同时,添加任意多个产品。

        public class Product
        {
            [DisplayName("产品名称")]
            public string Name { get; set; }
        }
     
        public class Category
        {
            [DisplayName("类别名称")]
            public string Name { get; set; }
            private IList<Product> _products = new List<Product>();
     
            public IList<Product> Products
            {
                get { return _products; }
                set { _products = value; }
            }
        }  
     
       
    □ 思路

    控制器方法能接收的格式为:
    Category.Name
    Category.Products[0].Name
    Category.Products[1].Name
    ...

    前台视图使用jquery动态生成input,并把input的name属性设置成Category.Products[i].Name格式。

     

    □ Home/Index.cshtml视图

    @model AddingMultipleNestedData.Models.Category
     
    @{
        ViewBag.Title = "Index";
        Layout = "~/Views/Shared/_Layout.cshtml";
    }
     
    @using (Html.BeginForm("Create", "Home", FormMethod.Post, new {id = "addForm"}))
    {
        <div>
            @Html.LabelFor(m => m.Name)
            @*@Html.EditorFor(m => m.Name)*@
            @Html.TextBox("Category.Name")
        </div>
        <div id="products"></div>
        <div>
            <input id="btnAddProduct" type="button" value="添加产品"/>
        </div>
        <div>
            <input type="submit" value="提交"/>
        </div>
    }
     
    @section scripts
    {
        <script type="text/javascript">
            $(function() {
                var noOfProducts = 0;
                $('#btnAddProduct').click(function() {
                    var product = getNestedName("Category.Products", noOfProducts);
                    noOfProducts++;
                    $('#products').append("<input type='text' name='"+product+".Name' /><p>");
                });
     
            });
     
            function getNestedName(itemName, itemNumber) {
                return (itemName + "[" + itemNumber + "]");
            }
        </script>
    }
     

    没有添加产品前:

    1

     

    添加产品集合:

    2

    □ HomeController

            public ActionResult Index()
            {
                return View();
            }
     
            [HttpPost]
            public ActionResult Create(Category category)
            {
                return View();
            }

    断点调试:       

    3

     

      更新 2014.05.07

    以上做法至少有二个弊端:

    1、无法对新添加的集合属性对应的个体进行验证。
    2、如果破坏集合元素的连续性,会影响控制器不能完全接收所有集合记录。

    Category.Name
    Category.Products[0].Name
    Category.Products[3].Name  
    Category.Products[6].Name  

    控制器只能接收到集合中的第一条记录,即Category.Products[0].Name,也就是说,一旦集合元素不是连续的,控制器将不能接收到全部集合记录。

    把noOfProducts++;改成noOfProducts = noOfProducts + 3;

    4

     

    断点调试: 
    5
    只能接收到一条记录。

    在下一篇中,将寻找一种既能验证集合元素,控制器又能接收不连续集合元素的解决方案!

     

      关于3楼刘慧心所提的问题

    总体来说,问题处在:
    <input type="hidden" name="CgdModel.Ubis.Index" value="indexA" />
    <input type="text" name="CgdModel.Ubis[indexA].Fdt"...
    <input type="text" name="CgdModel.Ubis[indexA].Memo...

     

    每一组Ubis属性所对应的Model,都对应着value值不同的隐藏域,大体应该这样:
    <input type="hidden" name="CgdModel.Ubis.Index" value="0" />
    <input type="text" name="CgdModel.Ubis[0].Fdt"...
    <input type="text" name="CgdModel.Ubis[0].Memo...

     

    <input type="hidden" name="CgdModel.Ubis.Index" value="1" />
    <input type="text" name="CgdModel.Ubis[1].Fdt"...
    <input type="text" name="CgdModel.Ubis[1].Memo...
    ...

    □ 假设您的Models是这样:

        public class CgdModel
        {
            public string Id { get; set; }
            public string Name { get; set; }
            public IList<Ubis> Ubis { get; set; }
        }
     
        public class Ubis
        {
            public string Fdt { get; set; }
            public string Memo { get; set; }
        }

     

    □ 假设CgdController是这样:

            public ActionResult Create()
            {
                return View(new CgdModel());
            }
     
            [HttpPost]
            [ValidateAntiForgeryToken]
            public ActionResult Create(CgdModel cgdModel)
            {
                if (!ModelState.IsValid)
                {
                    return View(cgdModel);
                }
                return Content("ok");
            }

     

    □ CgdController/Create.cshtml大致是这样:

    @model VariableCollection.Models.CgdModel
     
    @{
        ViewBag.Title = "Create";
        Layout = "~/Views/Shared/_Layout.cshtml";
    }
     
    @using (Html.BeginForm())
    {
         @Html.AntiForgeryToken()
        <input type="submit" value="产生采购单" />
        <fieldset>
            <legend>采购单</legend>
            
            <div class="editor-label">
                @Html.LabelFor(model => model.Name)
            </div>
            <div class="editor-field">
                @Html.EditorFor(model => model.Name)
                @Html.ValidationMessageFor(model => model.Name)
            </div>
        </fieldset>
        
        <fieldset>
            <legend>明细</legend>
            <table>
            @for (int i = 0; i < 3; i++)
            {
                <tr>
                    <td><input type="hidden" name="Ubis.Index" value="@i" /></td>
                    <td>Fdt @i<input type="text" name="Ubis[@i].Fdt" /></td>
                    <td>Memo @i<input type="text" name="Ubis[@i].Memo" /></td>
                </tr> 
            }
            </table>
        </fieldset>
    }
     

     

    6

     

    断点调试,可以接收到来自视图的集合所有元素数据:
    7

  • 相关阅读:
    js工具库
    细说log4j之log4j 1.x
    细说log4j之概述
    细说RESTful API安全之概述
    【转】javascript代码混淆和压缩
    细说RESTful API之入门介绍
    j2ee应用开发调试工具
    java定时器实现总结
    浏览器书签同步工具
    简单备份mysql数据库策略及实现方式
  • 原文地址:https://www.cnblogs.com/darrenji/p/3696415.html
Copyright © 2020-2023  润新知