我有一个复杂的表单,具有视图模型的层次结构,我想知道如何构造代码,以便我的控制器不会包含所有操作的处理程序。
这是一个简化的示例: 使用相应的 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,并由不同的控制器处理。但是当使用这种方法时,我可能会丢失相同的数据。例如:如果用户更改了名字,然后点击了删除地址按钮,那么名字将不会被 POST 回服务器,并且更改将丢失。
这给我留下了整个页面的一个表格。这意味着所有动作都应该由单个控制器类处理。我真的不喜欢这种方法,因为:
- 我最终会得到包含所有按钮的动作处理代码的大而胖的控制器
- 或者我将在我的控制器中有一个大的 switch 语句,它会识别动作,定位单独的类,知道如何处理动作,然后将处理委托给它(哎呀!这听起来像在中编写 windows 消息事件处理代码1990 年代 – WindowProc)
我已经阅读了有关 Html.ActionFor 的信息,它使您可以从视图中调用单独的控制器,但我认为这也不是一个好方法(它发生在视图被呈现时,这是不正确的)。
所以,总而言之,这又是一个问题:有没有办法处理从复杂视图模型的不同部分触发的动作/事件,这样我就不会在控制器中弄得一团糟?实际应用程序的最佳实践是什么(不是 Visual Studio 脚手架生成的 101 个 CRUD 示例)
更新:请注意,这只是一个简化的示例 - 实际上,视图模型要复杂得多,并且可以执行更多操作。我正在询问在 ASP.NET MVC 应用程序中构造控制器中的代码(或将其移动到单独的类)的一般方法。WebForms 提供了用户控件,使我们能够封装视图部分 (ASCX) 和事件处理程序。MVC 有一个很好的封装视图的解决方案,我正在尝试找到构建逻辑/事件处理程序的正确方法。