我一直在研究这个MVC 3 Razor应用程序,并且通常使用视图模型来查看我的视图。
我的视图模型中包含的信息数量多于我在表单中与之交互的特定实体。所以我的GET动作处理程序将初始化视图模型并为每个属性提供预期的值等。
在我的POST动作处理程序中,我检查模型状态是否有效,如果不是,我重新显示有错误的表单/视图。
在我的POST动作处理程序中,我发现自己必须从我的GET动作处理程序中复制代码才能再次重新呈现视图。如何实现控制器操作,以便我不必复制负责收集视图模型数据的代码?
我试过让我的动作处理程序同时处理POST和GET但是我有输入参数来处理。我的POST动作处理程序将视图模型作为输入参数,但GET动作处理程序不会。
答案 0 :(得分:7)
您的POST处理程序可以从GET处理程序返回ActionResult,如下所示:
public ActionResult SomePageGet() {
var model = new SomePageViewModel();
// Populate ViewModel:
...
return View("SomePageGet", model);
}
[HttpPost]
public ActionResult SomePagePost(SomePageViewModel input) {
// Validate the model:
...
if (!ModelState.IsValid) {
// Return the GET page, with error messages:
return SomePageGet();
}
return View("Success");
}
由于ModelState包含所有错误消息(和无效输入),GET页面将正常显示它们。
答案 1 :(得分:4)
在这种情况下,我们为视图模型创建构建器。
查看this post下的选项3。
答案 2 :(得分:0)
您可以简单地将公共代码重构为您正在处理的主要实体的扩展方法。
然后在停留DRY
时,可以多次调用它。
我并不确切知道该公共代码的功能是什么,但主要是它将是丰富演示的相关数据。
在这种情况下,我更喜欢的解决方案是让视图使用RenderAction从另一个动作加载额外的数据,这可以在以后重构为AJAX页面更新,保持DRY
并分离操作的关注点。
答案 3 :(得分:0)
“......我发现自己不得不复制代码......”
我不明白为什么;为什么你不能简单地在你的控制器中创建一个成员并调用它?并非控制器中的所有内容都必须是Action。但你可能想看看建设者,而不是@ataddeini建议的。
答案 4 :(得分:-1)
您的POST操作方法应该只能将viewmodel类型作为参数,而不是所有单独的数据。如果viewmodel构建起来比较复杂,您可能希望为视图模型编写一个可以执行更复杂工作的模型绑定器(您的操作方法仍然会将VM类型作为参数)。
[HttpPost]
public ViewResult MyAction(MyViewModel model) {
// model should now be fully populated; check ModelState.IsValid though in case there are errors (such as the user entering "abc" for an int property)
}