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

时间:2013-10-19 15:33:24

标签: c# asp.net-mvc

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

这是一个简化的例子: Sample view for a complex 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; }
}

我知道如何在单独的组件中分离页面每个部分的呈现:我使用的是@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有一个很好的封装视图的解决方案,我正在尝试找到构建逻辑/事件处理程序的正确方法。

1 个答案:

答案 0 :(得分:0)

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

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

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

通过这种方式,您将对CustomerData字段集进行简单的编辑后期操作,2用于在弹出窗口中显示数据的操作,以及一些用于操作地址部分的javascript。