c# - 具有域驱动设计的 MVC .NET 表单

标签 c# asp.net-mvc binding

我在大多数 .NET MVC 示例中看到的模式是让您的模型成为在 Controller 和较低层之间传递的对象,并直接与这些对象进行表单绑定(bind)。我选择了 domain-driven我在层之间传递域对象的方法。想法是将这些对象传递到 View 中。

我遇到的问题是涉及带有表单的页面。我打算为表单在返回的路上绑定(bind)到单独的对象(其中也将包含验证注释)。我将它与域对象分开,因为单个对象可能会被不同的页面更新,每个页面都有自己的验证要求(例如,一个人的地址可能甚至不会显示在一个页面上,但在另一个页面上需要,所以验证并不总是适用于通用域对象)。一旦您回发表单并需要显示错误,这会使事情变得复杂。

以更新页面为例。我将 View 键入我的域 Person 对象,页面将从中填充它的字段值。回发操作将采用该页面的表单对象并对其进行验证。如果它通过了,我使用 automapper将值复制到表单外的域对象并保存。这一切都有效。它崩溃的地方是在出现错误时重新显示该页面。如果将其键入域对象,我最终只会根据旧值而不是用户输入的值重新填充字段。如果它被输入到表单对象,那么我需要将我所有的域对象转换为每个页面的这些表单对象(如果我需要一些值,我仍然可能必须传入域对象,我将对该页面使用只读).

我确信我忽略了这里的某些东西/过于复杂了。

更新 由于@Charlino 所说的内容,在玩耍后发现了一个有趣的发现。如果我使用强类型的 html 帮助程序进行输入 (Html.TextBoxFor()),即使将 View 键入域对象,它也会记住这些值。如果我使用通用的 (Html.TextBox()) 或原始 HTML,它似乎没有。

最佳答案

我最终会为每个 View 创建一个 ViewModel 对象。

这是一些更前期的工作,因为我必须定义 ViewModel 和映射,但该代码非常简单明了,只需几秒钟即可编写完成。

通常,当我需要一个表单时,我会创建一个单独的 Form 对象,并让 ViewModel 包含它。

public class MyViewModel 
{
    public string SomeNonFormDisplayValue { get; set; }
    public bool AnotherDisplayOnlyValue { get; set; }
    public IEnumerable<Tuple<int, string>> SelectionListItems { get; set; }

    public MyViewsForm Form { get; set; }
}


public class MyViewsForm
{
    public string EditableProperty { get; set; }
    public int SelectionListItemId { get; set; }
}

我将我的 View 输入到 ViewModel,但我让 Post Action 方法只采用该形式。

public class MyController
{
    [HttpGet]
    public ActionResult Edit() { ... }

    [HttpPost]
    public ActionResult Edit(MyViewsForm form) { ... }
}

我还创建了查​​询方法来检索 ViewModel,一个填充表单,另一个不填充 - 因为当我返回有错误的 POST 表单时。

关于c# - 具有域驱动设计的 MVC .NET 表单,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4326378/

相关文章:

c# - 在 ASP.Net 5 中配置 Azure Blob 访问

javascript - 使用 Javascript MVC4 访问从数据库返回的对象

WPF 在 CompositeCollection 中绑定(bind) MenuItem 不起作用

wpf - 绑定(bind)到 datacontext parent-WPF 的属性

c# - 发生更改时,List<string> 不会更新 UI

c# - 如何将计算机音频传递给程序以进行可视化?

c# - 如何在C#中使用三元运算符

c# - C#中泛型数值类型的讨论

javascript - Ajax .BeginForm 在 IE9 中返回空白 View

c# - LINQ 和 EF6 : The context cannot be used while the model is being created