Asp.Net MVC行动 - 关注点分离/单一责任原则

Nei*_*eil 7 asp.net-mvc separation-of-concerns

在计算机科学中,我们被教导每种方法应该只做一件事,一件事.我有点困惑,然后我们看到MVC行为如下所示作为良好实践的例子:

    [AcceptVerbs(HttpVerbs.Post), Authorize]
    public ActionResult Edit(int id, FormCollection collection) {

        Dinner dinner = dinnerRepository.GetDinner(id);

        if (!dinner.IsHostedBy(User.Identity.Name))
            return View("InvalidOwner");

        try {
            UpdateModel(dinner);

            dinnerRepository.Save();

            return RedirectToAction("Details", new { id=dinner.DinnerID });
        }
        catch {
            ModelState.AddModelErrors(dinner.GetRuleViolations());

            return View(new DinnerFormViewModel(dinner));
        }
    }
Run Code Online (Sandbox Code Playgroud)

基本上这段代码提供了很多功能:

  1. 定义如何访问Action - 仅限Post
  2. 定义谁可以访问Action - Authorize
  3. 访问持久性机制 - dinnerRepository
  4. 访问状态信息 - (User.Identity.Name)
  5. 将NameValueCollection转换为强类型对象 - UpdateModel()
  6. 为每个指定3个可能的ActionResults和内容--InvalidOwner/Details/Edit视图

对我来说,这似乎对一种方法的责任太多了.它也是一个相当简单的动作,即它不处理常见的情况,如:

  1. 检查业务规则 - "永远不要信任用户输入"
  2. 导航路径 - 成功保存后始终返回"详细信息"
  3. 不同的返回类型 - 有人想从网格中调用"编辑"并需要一个JsonResult吗?
  4. 更好的错误处理 - 如果在GetDinner(id)期间无法访问数据库,则为YSOD
  5. 构建其他视图数据 - 用于下拉列表的SelectLists

不要太提及围绕这种方法所需的测试量,即FormCollection/UserIdentity/Authorization Provider/Repository/etc的模拟/伪造.

我的问题是我们如何避免在控制器操作中塞入如此多的东西?

我倾向于认为"意见"是一个伟大的概念,尤其是"Thunderdome Principle".虽然我非常尊重参与构建FubuMVC的人及其背后的原因,但我需要一些我现在可以使用的东西.

编辑 - 好吧,我似乎是在追求这样的事情 - Opinionated Controller.我需要进一步检查它,因为它是MVC预览5所以我可能需要自己更新它.

Chr*_*isb 1

我对你的帖子有点困惑。首先你抱怨这个行动做得太多了,然后你又抱怨没有做得更多。

编辑添加:

老实说,这不是一个非常复杂的控制器操作。这是否是最佳实践示例是有争议的,但是,您可能不会得到比这更简单的结果。我想你可以将其中一些分解成单独的例程,但在某些时候你必须决定在哪里划清界限。最终,我们作为程序员必须编写软件。设计原则很棒,但如果我们对它们过于严格,那么什么也建不起来。