【发布时间】:2016-04-19 20:30:08
【问题描述】:
在我目前正在编写的 ASP.Net MVC 5 应用程序中,一个 Material 可以有多个名称 (MaterialNames)。我已经构建了一个 Web 界面来添加、编辑和删除材料的 Edit 和 Create 页面上的材料名称。为了实现这一点,我在那些名为Material.MaterialNames 的页面上有多个text-inputs。可以使用 javascript 在客户端添加和删除这些以更改名称的数量。我不需要inputs 的names 中的索引,因为用户应该查看和编辑的数据只是字符串的平面列表。
这些是我的模型的相关部分:
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>,现在一切都会很好。在我的情况下,模型绑定器无法从作为表单数据传递的多个字符串值创建MaterialNames。我相信解决此问题的默认方法是
编写自定义模型绑定器
像in this answer(= 覆盖BindProperty 并仅更改一个 PropertyType 的行为)这样的做法是个好主意吗?我会将它与globally registering the binder 结合起来,用于MaterialVM 类型。
我错过了一个更简单的选择吗?
难道不能只为默认绑定器提供一种将简单类型转换为复杂类型的方法吗?我的方法如何编写自定义模型活页夹正确吗?是否还有其他我遗漏的选项可以让这更直观?
【问题讨论】:
-
我知道使用索引的可能性。我一直在寻找没有它们的解决方案,因为我认为它们会产生很多 html-overhead 而没有任何需要,因为我每个索引只有一个字符串。
-
由于您编辑复杂对象的集合,因此您必须使用索引器(没有办法匹配
Name属于哪个Id和MaterialId属性否则,特别是如果您动态即使您要创建自定义 ModelBinder). You can only avoid the indexers if your property ispublic ListMaterialNames { get; set; } ,也可以添加和删除项目 -
理论上我不需要比我拥有的更多信息。我将不得不为活页夹添加索引。我的想法是实现即overridden cast 以使活页夹能够将字符串转换为
MaterialNames。这就引出了一个问题:活页夹支持的非复杂类型是硬编码的吗?活页夹是否使用任何类型的标准反序列化方法以便我可以在那时添加转换逻辑? -
这样做没有任何意义。假设您有现有的项目 M1、M2 和 M3,并且在视图中删除 M2 并添加 M4 并将 M3 的名称更改为 M5。除非您具有关联的
ID属性,否则您无法确定需要添加哪些项目,更新数据库中的删除,并且唯一的方法是提供索引器。
标签: c# asp.net asp.net-mvc-5 model-binding