如何在ASP.NET MVC中处理来自不同部分的复杂ViewModel的动作

mat*_*tra 5 c# asp.net-mvc

我有一个复杂的形式,具有视图模型的层次结构,我想知道如何构造代码,以便我的控制器不会包含所有操作的处理程序.

这是一个简化的例子: 复杂ViewModel的示例视图 使用相应的ViewModel:

public class MyPageViewModel
{
   public List<TabViewModel> Tabs {get; set; }
   public CustomerViewModel Customer;
}

public class TabViewModel
{
    public string DisplayLabel { get; set; }
    public bool Selected { get; set; }
}

class CustomerViewModel
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public List<Address> Addresses { get; set; }
}  

public class Address
{
    public string Street { get; set; }
    public string City { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

我知道如何在单独的组件中分离页面每个部分的渲染:我正在使用@Html.EditorFor并且@Html.DisplayFor对模型的每个部分都有一个单独的视图(由上图中的红色矩形表示).这很好用.ViewModel的一部分(例如TabViewModel类)也可以在其他页面上重复使用.

我遇到事件处理逻辑问题.可以在此页面上执行的操作很少(以蓝色背景表示).一种可能性是使用多个FORM标签 - 每个标签用于上图中的一个红色矩形.每个表单都有不同的操作URL,并由不同的控制器处理.但是当使用这种方法时,我可能会丢失相同的数据.例如:如果用户更改了First Name,然后点击Remove Address按钮,则First Name将不会被POST回服务器,并且更改将丢失.

这为我留下了整个页面的一个表单.这意味着所有操作都应由单个控制器类处理.我真的不喜欢这种方法,因为:

  • 我最终会得到一个包含所有按钮动作处理代码的大胖控制器
  • 或者我会在我的控制器中有一个很大的switch语句,它会识别动作,找到单独的类,知道如何处理动作,然后将处理委托给它(哎呀!这听起来就像编写windows消息事件处理代码一样) 20世纪90年代 - WindowProc)

我已经阅读了Html.ActionFor,它可以让你从View中调用一个单独的控制器,但我认为这也不是好方法(它在渲染视图时发生,这是不正常的).

总而言之,这里又是一个问题:有没有办法处理从复杂视图模型的不同部分触发的动作/事件,以至于我不会在控制器中弄得一团糟?实际应用程序的最佳实践是什么(不是由Visual Studio脚手架生成的101个CRUD示例)

更新:请注意,这只是一个简化的示例 - 在现实中,视图模型要复杂得多,还有更多可以执行的操作.我问的是在ASP.NET MVC应用程序中构造控制器中的代码(或将其移动到单独的类)的一般方法.WebForms提供了用户控件,使我们能够封装View部件(ASCX)和事件处理程序.MVC有一个很好的封装视图的解决方案,我正在尝试找到构建逻辑/事件处理程序的正确方法.

use*_*656 0

我将为客户数据字段集添加一个“保存”按钮,并在用户单击“保存”按钮时保存/发布所有客户数据。这样,在您的编辑帖子操作中,您将只使用CustomerViewModel.

Address“添加新地址”和“删除此地址”将添加和删除使用 javascript所需的 html 。

“搜索现有客户”和“从外部数据库选择”可以显示一个弹出窗口,其中包含表单中相应部分所需的数据。使用Ajax来获取数据。

这样,您将拥有一个针对 CustomerData 字段集的简单编辑帖子操作、2 个用于在弹出窗口中显示数据的操作,以及一些用于操作地址部分的 javascript。