MVC5自定义绑定:复杂类型列表的字符串列表

时间:2016-04-19 20:30:08

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

在我正在编写的ASP.Net MVC 5应用程序中,一个Material可以有多个名称(MaterialName s)。我已经构建了一个Web界面,用于在材料的EditCreate页面上添加,编辑和删除材料的名称。为实现此目的,我在名为text的网页上有多个input - Material.MaterialNames。可以使用javascript添加和删除客户端以更改名称的数量。我不需要name的{​​{1}} s中的索引,因为用户应该看到和编辑的数据只是一个扁平的字符串列表。

这些是我模特的相关部分:

input

如果public class MaterialVM { public Material Material { get; set; } // ... } public class Material { public int Id { get; set; } public List<MaterialName> MaterialNames { get; set; } // ... } public class MaterialName { public int Id { get; set; } public string Name { get; set; } public int MaterialId { get; set; } } 类型为Material.MaterialNames,那么现在一切都会好起来的。在我的情况下,模型绑定器不能从作为表单数据传递的多个字符串值创建List<string>。我相信修复此问题的默认方法是

编写自定义模型绑定器

in this answer一样(=覆盖MaterialName并只更改一个PropertyType的行为)是不是一个好主意?我会将globally registering the binderBindProperty类型结合起来。

我是否想念一个更简单的选项?

是不是可以只提供默认绑定器一种方法来转换/转换/序列化/ ...简单类型到复杂类型?我的方法是如何正确编写自定义模型绑定器的?我还缺少哪些其他选项会让这更直观吗?

3 个答案:

答案 0 :(得分:2)

您可以使用默认模型绑定器绑定复杂类型,但需要向重复控件的模板添加.Index属性。

这是我能想到的最简单的例子:

@model WebApplication25.Models.MaterialVM

@using (Html.BeginForm())
{
    @Html.HiddenFor(model => model.Material.Id)
    <table id="output">
        <tr>
            <th>Name</th>
            <th>MaterialId</th>
            <th>Id</th>
        </tr>

    </table>
    <button id="add-more" type="button">Add Another</button>
    <button type="submit">Submit</button>
}
@section scripts{
    <script>
        (function (window) {
            "use strict";
            var index = 0;
            $("#add-more").on("click", function () {
                $("#output").append(
                  "<tr><td>" +
                  "<input type='hidden' name='Material.MaterialNames.Index' value='" + index + "' />" + // add in the index
                  "<input type='text' name='Material.MaterialNames[" + index + "].Name' /></td>" +
                  "<td><input type='number' name='Material.MaterialNames[" + index + "].MaterialId' /></td>" +
                  "<td><input type='number' name='Material.MaterialNames[" + index + "].Id' />" +
                  "</td></tr>");
                index++;
            });

        }(window));
    </script>
}

此示例应导致它们出现在您的视图模型中: Model bound data list

答案 1 :(得分:1)

视图模型应该适应视图,因此应该有一个

List<string> materialNames

MVC绑定将绑定到视图模型。

然后在控制器或您处理映射的任何层中,您可以将 MaterialVM 映射到材料

答案 2 :(得分:0)

如果您将MaterialVM缓存在会话变量中,或IdMaterialNames缓存Dictionary<int, List<string>>,那么您可以回复id的操作和List<string>名称。使用id,您可以查找材料,然后更新模型。

或者,在JS中,您可以JSON.stringify表单数据,然后在服务器端解析它。