在试图降低我的MVC控制器的尺寸,我重构了很多逻辑伸到服务(不过,如果它被纳入模型同样的问题也适用)。我经常发现我是直接设置ViewData
和/或TempData
的信息我想被显示给用户,如:将TempData和/或ViewData传递给服务是否是一种好的做法?
var repoUser = new UserRepository();
var foundUser = repoUser.GetUser(userId);
if (foundUser == null) {
ViewData["ErrorMessage"] = "Could not find user with ID {0}.".FormatWith(userId);
return View("UsersRegister");
}
当然,只要你进入一个服务类,你输了直达ViewData
,TempData
,像View()
或RedirectToAction()
方法,所以我试图找出对付它的最好实践。两种解决方案浮现在脑海中:
创建一个包含各条关于控制器应该做什么信息类,从服务传回,如:
public class ResponseInfo { public string Name { get; set; } public bool DoRedirect { get; set; } public object RedirectRouteValues { get; set; } public string InfoMessage { get; set; } public string ErrorMessage { get; set; } }
尝试,并允许服务方法直接获得的东西像
ViewData
和TempData
,例如:public ActionResult ToggleUserAttended(int eventId, int userId, HttpRequestBase request, TempDataDictionary tempData, ViewDataDictionary viewData, Func<string, object, ActionResult> redirectAction) { //... var repoUser = new UserRepository(); var foundUser = repoUser.GetUser(userId); if (foundUser == null) { tempData["ErrorMessage"] = "Could not find user with ID {0}.".FormatWith(userId); return redirectAction("UsersRegister", new { id = eventId, returnUrl = request.QueryString["returnUrl"] }); } //... }
...然后在控制器:
return _svcEvent.ToggleUserAttended(123, 234, Request, TempData, ViewData, (name, routeVals) => RedirectToAction(name, routeVals));
对于编号1中,控制器将有更多的逻辑看ResponseInfo
对象,并确定是否重定向做,显示视图,堵塞错误或信息消息分成TempData
或ViewData
等Number 2几乎可以让一个单线控制器,但是你让服务非常清楚控制器的具体内容。但是,服务总是与控制器紧密相连,所以这是一个问题吗?会1或2是最佳做法,还是我没有列出的其他东西?
GOD NO。将这样的事情转移到ActionFilter中......不要让你的服务访问像ViewData和TempData这样的前端概念。 – 2013-03-19 10:50:50
@SimonWhitehead那么你基本上是说将这些东西留在控制器中?那些错误消息本身呢?一个更完整的答案将不胜感激。 – Jez 2013-03-19 11:00:22
您有没有考虑使用'ModelState'来显示这些错误?您可以在服务层错误列表和“ModelStateDictionary”之间映射UI层。这将您的服务从您的用户界面中分离出来。你甚至可以编写你自己的'ActionResult',这样它就可以很好地返回它,并且使得你的动作显着缩小。我现在不是靠近PC来键入示例。 – 2013-03-19 11:34:51