【问题标题】:Best Practice for Lists of Complex Types in ASP.NET MVC 3ASP.NET MVC 3 中复杂类型列表的最佳实践
【发布时间】:2011-05-05 05:53:25
【问题描述】:

这是我的第一个 SO 问题,与其说是“我该怎么做”,不如说是“最干净的方法是什么”,因为我看到了几种方法,但似乎都不是吸引我。

这是一个有点复杂的问题来描述。本质上,我有一个添加/编辑视图,允许用户编辑某些对象的字段。这个对象非常复杂:它有一些字段,并且有一个复杂对象的子列表。每个复杂对象大约有 40 个字段(主要是复选框、单选按钮和日期/时间)。我已将其表示为选择列表:


(来源:fortheloot.com

添加按钮会生成包含各种字段的对话框。

问题来了。当用户接受对话框并且对话框关闭时,我现在必须将这些数据存储在某个地方,以便用户可以在实际提交表单之前进一步编辑它或添加其他子项。

最明显的方法是为每个子对象创建一组隐藏字段。因此,添加子项会将 40 多个隐藏元素添加到 <form> 元素。添加 10 个子项,您就有 400 个隐藏字段。这将正常工作,并且如果字段命名正确,将绑定到此模型:

public class AddEditModel
{
  [Display(Name = "ID")]
  public int? Id { get; set; }

  [Display(Name = "Name")]
  [Required]
  [StringLength(100)]
  public string Name { get; set; }

  public IList<EntryModel> Entries { get; set; }
  public class EntryModel { /* fields */ }
}

在模型绑定方面,这看起来不错,但在客户端,我必须跟踪数百个 DOM 元素,这对我来说似乎很麻烦。从 40 个其他元素中加载和卸载对话框的各种表单元素似乎......可能会更好。

理想情况下,我希望能够使用data- HTML 5 属性或jQuery 的data() 函数将数据作为javascript 对象存储在&lt;option&gt; 元素上,它们实际上是一回事。这将使事物的 javascript 方面更加简洁,但它不会在回发时自动绑定到模型。

如果有一种方法可以两全其美——在 &lt;option&gt; 元素上存储单个 JS 对象,甚至是单个 &lt;input type="hidden" /&gt; 元素(每个子项)——那仍然会绑定到模型在回发时正确,我觉得这个问题已经解决了。

【问题讨论】:

  • 丹宁。好问题,艰难的场景。 +1 :)

标签: c# asp.net-mvc-3


【解决方案1】:

您仍然需要一个 html 字段 (type=hidden) 才能将此数据发送回服务器。 (您可以使用 ajax 帖子,但这可能不是一个好主意)

我建议设计一个合理的对象模型来包含这些数据结构,并在每次将对象模型更改为 json 时将其序列化为 stringify

然后,当您回发表单时,json 将被发送到服务器,您可以使用 JavaScriptSerializer 将整个对象模型反序列化为一组用 c# 编写的类(可以模仿您在 javascript 中拥有的对象模型)类

编辑:

要反序列化一个json字符串,可以使用如下代码:

JavaScriptSerializer js = new JavaScriptSerializer(); 
var c = js.Deserialize<MyClass>(json);
return View(c);

如果您将 json 作为 post 消息正文回发(例如 $.ajax 或 $.post 方法),那么 MVC3 将自动发生绑定,您只需指定正确的内容类型:在邮政;请点击下面我评论中的链接,了解有关其工作原理的更多详细信息。

马丁

【讨论】:

  • 那么,您会使用自定义模型绑定器来完成模型那部分的 JSON 反序列化吗?
  • JsonValueProviderFactory,现在在 MVC3 中默认注册,可以自动绑定 json 对象,看看这篇文章(如果你使用 MVC3,你可以跳过一些):haacked.com/archive/2010/04/15/…
  • 嗯。因此,您的方法是将整个表单作为单个 JSON 对象发布,并让 MVC 模型绑定器根据内容类型检测到这一点。有趣的。我想仍然允许浏览器做一个正常的 FORM 帖子。听起来越来越像我需要一个自定义模型绑定器..
  • 您可以将json字符串保留在隐藏字段中,并将单个字符串参数绑定到该字段。然后,您可以使用我上面提到的类再一步来反序列化它以获取对象图。这不需要自定义模型绑定器,而是常规形式的回发
  • 最终,我使用了这种方法。我对它不是很满意,但它现在有效。
【解决方案2】:

您是否考虑过使用诸如骨干网或淘汰赛之类的 javascript 框架? https://stackoverflow.com/questions/5112899/knockout-js-vs-backbone-js-vs

【讨论】:

  • 提问作者:稍等片刻,仔细看看knockout.js
  • 上周我重写了这段代码以使用 Knockout。我过来了。只用了 3.5 年。
【解决方案3】:

由于我们一直使用 javascript,所以我也会坚持使用 javascript 来进行回发。当您在列表中输入新项目时,我将继续构建一个多维 javascript 数组,然后将数组转换为 json,然后通过 ajax 帖子将其发送到您的 MVC 路由。

只要 json 对象符合你的模型的命名标准,MVC 就会在到达 action 方法之前进行隐式模型绑定。

最简单、最优雅的方法是什么? Knockout.js! 在淘汰赛中,您将创建一个可观察的集合并添加到您的集合中,而无需使用 javascript 数组的肮脏语法。然后,在发布 ajax 帖子之前,您将调用敲除 toJSON 方法将集合转换为 json。

我强烈推荐在 Knockout 上观看 PluralSight 视频,然后下载源代码。

我会写一个示例,但我必须回去工作:)

【讨论】:

  • 感谢您的反馈。我真的需要看看淘汰赛。你能把我链接到你正在谈论的视频吗?谷歌提供了大量的结果。
  • 访问pluralsight.com,您会在javascript 类别下看到一个淘汰赛视频。 Multiplesight 是一项付费服务​​,但我强烈推荐...
  • 啊,我明白了。惊人的。非常感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-16
  • 2021-03-13
  • 1970-01-01
相关资源
最近更新 更多