c# - 如何在 ASP.NET MVC 中保持 Controller 较小?

标签 c# asp.net-mvc-3 controller refactoring

我有一个设计得很好的架构,其中 Controller 转到访问与数据库通信的存储库的服务。

因此, Controller 中的逻辑保持在最低限度,但我仍然有非常微妙的代码片段来执行一些任务,例如

  • 验证模型
  • 安排 Action 方法参数
  • 使用这些参数调用一些服务,如果模型现在无效,可能会验证结果并返回 View
  • 最终根据服务的结果生成一个模型,并将其返回。

一些较长的案例根据服务返回的“状态”做不同的事情。

举几个例子:

[HttpPost]
[AjaxOnly]
[Authorize]
public JsonResult Preview(string input)
{
    LinkResult parsed = linkService.ParseUserInput(input);
    if (parsed.Result == LinkParseResult.Used)
    {
        long? postId = parsed.Link.PostId;
        if (postId.HasValue)
        {
            Post post = postService.GetById(postId.Value, false);
            return Json(new
            {
                faulted = "used",
                link = DetailsRoute(post),
                id = postId
            });
        }
        else
        {
            return Json(new { faulted = "invalid" });
        }
    }
    else if (parsed.Result == LinkParseResult.Invalid)
    {
        return Json(new { faulted = "invalid" });
    }
    else
    {
        Link link = parsed.Link;
        if (link.Description != null && link.Description.Length > 200)
        {
            link.Description = link.Description.Substring(0, 200);
        }
        return AjaxView(link);
    }
}

并且(Post来自域,PostModel是 View 模型)

private PostModel PostModelConverter(Post post)
{
    Link link = post.Link;
    if (link == null)
    {
        throw new ArgumentException("post.Link can't be null");
    }
    if (link.Type == LinkType.Html)
    {
        return new PostedLinkModel
        {
            Description = link.Description,
            PictureUrl = link.Picture,
            PostId = post.Id,
            PostSlug = postService.GetTitleSlug(post),
            Timestamp = post.Created,
            Title = link.Title,
            UserMessage = post.UserMessage,
            UserDisplayName = post.User.DisplayName
        };
    }
    else if (link.Type == LinkType.Image)
    {
        return new PostedImageModel
        {
            PictureUrl = link.Picture,
            PostId = post.Id,
            PostSlug = postService.GetTitleSlug(post),
            Timestamp = post.Created,
            UserMessage = post.UserMessage,
            UserDisplayName = post.User.DisplayName
        };
    }
    return null;
}

这引发了一个问题,即 View 模型是否真的应该按照规则存在于 Web 项目中,或者它们实际上可以成为域或其他项目的一部分。

除了可能使用接收链接并截断描述的 PreviewModel 之外,我不确定我可以对预览操作做很多事情,但这会像两行一样保存。

模型转换器可能应该在其他地方,但我不知道它应该在哪里。

我想到的另一点是,我是否应该使用 partial 关键字(将其用于自动生成的类之外的其他东西是一种不好的做法?)或添加路由来拆分此 Controller 根据请求的操作或使用的 http 方法使用不同的 Controller ,通常的处理方法是什么?

最佳答案

这已经被问过好几次了:
Business logic in the controller
Where should I put my controller business logic in MVC3
Keep Controllers Thin

以及其他地方写的:
ASP MVC Best Practices - Skinny Controllers
Keep Controllers Thin

社区似乎达成了很好的共识,即这种逻辑属于 Controller 之外。通常在模型(或 ViewModel)中,但某处在业务层中。

作为最后的说明,不建议对非自动生成的代码使用 partials。如果拆分事情有意义,那就这样做。想想你们分手的原因是什么。这将视具体情况而定。

关于c# - 如何在 ASP.NET MVC 中保持 Controller 较小?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11748403/

相关文章:

JavaFx 嵌套 Controller ?

C# - 覆盖 WebBrowserDocumentCompletedEventHandler 的事件参数

c# - 数据绑定(bind)到数据表或gridview时出错

asp.net-mvc-3 - 如何使用 JQuery 和 tokenInput 触发 Controller

javascript - MVC3,同一个页面View之间的切换

php - Laravel 5.2 理解 "fat model, skinny controller"

c# - 来自列表的 SqlBulkCopy<>

c# - 无法直接使用 TestStack.White 单击按钮

c# - 如何更新我的 Entity Framework

php - Controller 能否捕获模型抛出的异常?