如何在ASP.NET MVC中保持控制器小?

bev*_*qua 10 c# refactoring controller asp.net-mvc-3

我有一个设计精良的架构,控制器访问服务,这些服务访问与数据库通信的存储库.

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

  • 验证模型
  • 安排动作方法参数
  • 使用这些参数调用某些服务,如果模型现在无效,则可以验证结果并返回视图
  • 最后从服务的结果中生成一个模型,然后返回.

一些较长的情况根据服务返回的"状态"执行不同的操作.

这里有几个例子:

[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);
    }
}
Run Code Online (Sandbox Code Playgroud)

和(Post来自域,PostModel是视图模型)

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;
}
Run Code Online (Sandbox Code Playgroud)

这提出了一个问题,即视图模型是否确实应该在Web项目中作为规则,或者它们实际上可能是域或其他项目的一部分.

我不确定我可以对预览操作做多少,除了可能使用接收链接的PreviewModel并截断描述,但这样可以节省两行.

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

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

Kye*_*ica 5

这已被多次询问:
业务逻辑控制器
我应该在哪里把我的控制器业务逻辑MVC3
保持控制器瘦

以及其他地方的文章:
ASP MVC最佳实践 - 瘦控制器
保持控制器薄

社区似乎已达成共识,这种逻辑属于控制器之外.通常在模型(或ViewModel)中,但在业务层的某个地方.

最后要注意的partials是,不鼓励使用非自动生成的代码.如果分裂事物是有意义的,那么这样做.试想一下你分裂它的原因是什么.这将是一个案例的事情.