MVC - 服务层应该如何与控制器通信

发布于 2024-12-21 18:27:18 字数 771 浏览 3 评论 0原文

我一直在为我的控制器操作使用以下模式:

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

莫言歌 2024-12-28 18:27:18

如果您选择例外,请小心,这些例外的费用很高。它还为您的控制器代码提供了额外的嵌套,具体取决于可能抛出的异常数量。您实际上应该仅在异常情况下抛出异常,而不是应由应用程序的正常流程处理的异常。

我会采用 Wouter de Kort 建议的另一条路线,将服务的返回类型用于消息传递对象。您可以在简单枚举上键入返回消息对象,其中包含服务可能遇到的各种情况。这些在控制器中看起来更好,因为您可以使用 switch/case 而不是 try/catch 来处理枚举。

更新

消息传递对象可能是什么样子:

public interface IServiceAbc
{
    ServiceResponse InvokeMyService([params]);
}

public enum ResponseScenario
{
    Success,
    DatabaseFailed,
    BusinessRuleViolated,
    ValidationRuleViolated
}

public class ServiceResponse
{
    public ResponseScenario Scenario { get; internal set; }
    public string Message { get; internal set; }
}

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:

public interface IServiceAbc
{
    ServiceResponse InvokeMyService([params]);
}

public enum ResponseScenario
{
    Success,
    DatabaseFailed,
    BusinessRuleViolated,
    ValidationRuleViolated
}

public class ServiceResponse
{
    public ResponseScenario Scenario { get; internal set; }
    public string Message { get; internal set; }
}
一笑百媚生 2024-12-28 18:27:18

如果您想在发生错误时返回详细消息,您始终可以使用异常。也许可以使用特定细节定义您自己的细节,或者重用 .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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文