我有一个设计精良的架构,控制器访问服务,这些服务访问与数据库通信的存储库。
因此,控制器中的逻辑保持在最低限度,但我仍然有非常微妙的代码片段来执行某些任务,例如
根据服务返回的“状态”,某些较长的情况会执行不同的操作。
这里有几个例子:
[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
是视图模型)
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;
}
这提出了一个问题,即视图模型是否真的应该作为规则存在于Web项目中,或者它们实际上可能是域或其他项目的一部分。
我不确定我是否可以对预览操作做很多事情,除了可能使用接收链接的PreviewModel并截断描述,但这会节省两行。
模型转换器可能应该在其他地方,但我对应该在哪里一无所知。
我想到的另一点是,我是否应该使用partial
关键字拆分此控制器(将其用于除自动生成的类之外的其他方法是不好的做法?),或添加使用不同的路由控制器取决于请求的操作或正在使用的http方法,处理它的常用方法是什么?
答案 0 :(得分:5)
这已被问过几次:
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
社区似乎已达成共识,这种逻辑属于控制器之外。通常在模型(或ViewModel)中,但在业务层中某处。
最后请注意,不建议使用partials
来表示非自动生成的代码。如果分裂事物是有意义的,那么这样做。试想一下你分裂它的原因是什么。这将是一个个案的事情。
答案 1 :(得分:2)
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)
{
var model = AutoMapper.Map<PostedLinkModel>(post);
model.PostSlug = postService.GetTitleSlug(post);
return model;
}
else if (link.Type == LinkType.Image)
{
var model = AutoMapper.Map<PostedImageModel>(post);
model.PostSlug = postService.GetTitleSlug(post);
return model;
}
return null;
}
答案 2 :(得分:0)
控制器不包含任何域逻辑
控制器应该只负责:
验证输入
调用模型准备视图
返回视图或重定向到其他操作
如果您正在做任何其他事情,那么您在错误的地方做这件事,那就是您在Controller中所做的模范职责。
如果您遵循此规则,您的操作方法不会超过20 - 25行代码。 Ian Cooper有一篇优秀的帖子Skinny Controller Fat Model,请仔细阅读。