MVC - 服务层应该如何与控制器通信
我一直在为我的控制器操作使用以下模式:
public ActionResult Create(CreateViewModel model) {
if( !ModelState.IsValid ) {
return View(model);
}
var project = new Project {
Name = model.Name,
// ...
};
projectRepository.Add(project);
return RedirectToAction("Index");
}
这适用于简单的场景,但我遇到过一些存储库不够的情况。我创建了一个服务层/类,它将处理保存项目和任何额外的业务逻辑(不是具有流畅验证或数据注释的正常验证)。
public class ProjectService : IProjectService {
void AddProject(Project project) {
// do business logic
// ...
repository.Add(project);
}
}
我的服务层如何轻松地与我的控制器通信?
这些是我想要与控制器进行通信的类型:
- 业务逻辑/验证错误
- 数据库故障(无法保存等)
我怎样才能做到这一点而不只是从服务层返回真/假或状态代码?
I have been using the following pattern for my controller actions:
public ActionResult Create(CreateViewModel model) {
if( !ModelState.IsValid ) {
return View(model);
}
var project = new Project {
Name = model.Name,
// ...
};
projectRepository.Add(project);
return RedirectToAction("Index");
}
This works for simple scenarios, but I have had a few situations where a repository is not enough. I created a service layer / class that will handle saving the project and any extra business logic (not normal validations with fluent validation or data annotations).
public class ProjectService : IProjectService {
void AddProject(Project project) {
// do business logic
// ...
repository.Add(project);
}
}
How can my service layer easily communicate with my controller?
These are the types of things I would like to communicate to the controller:
- Business Logic / Validation errors
- Database Failures (failed to save etc.)
How can I do this without just returning true/false or status codes from the service layer?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果您选择例外,请小心,这些例外的费用很高。它还为您的控制器代码提供了额外的嵌套,具体取决于可能抛出的异常数量。您实际上应该仅在异常情况下抛出异常,而不是应由应用程序的正常流程处理的异常。
我会采用 Wouter de Kort 建议的另一条路线,将服务的返回类型用于消息传递对象。您可以在简单枚举上键入返回消息对象,其中包含服务可能遇到的各种情况。这些在控制器中看起来更好,因为您可以使用 switch/case 而不是 try/catch 来处理枚举。
更新
消息传递对象可能是什么样子:
Be careful if you choose exceptions, these are expensive. It gives your controller code extra nesting too, depending on how many exceptions may be thrown. You should really only throw an exception for an exceptional condition, not something that should be handled by the normal flow of your application.
I would go with the other route Wouter de Kort suggested, use the return type of the service for a messaging object. You can key a return message object on a simple enum with the various cases the service may encounter. These look better in the controller because you can handle the enum with a switch/case rather than a try/catch.
Update
What a messaging object may look like:
如果您想在发生错误时返回详细消息,您始终可以使用异常。也许可以使用特定细节定义您自己的细节,或者重用 .NET Framework 中已有的细节。
如果这不是一个选项,您总是可以返回一个包装类,它可以包含更详细的错误信息并在控制器中处理该信息。
If you want to return detailed messages when an error occurs you could always use Exceptions. Maybe define your own with specific details or reuse the ones that are already in the .NET Framework.
If that´s not an option you could always return a wrapper class which could contain more detailed error information and handle that in the Controller.