从服务返回什么到 ASP MVC Web 应用程序?

发布于 2024-12-28 22:49:36 字数 528 浏览 1 评论 0原文

现在,我有一个 ASP MVC Web 应用程序以及一个模型项目、一个服务项目、一个实用程序项目和一些用作一个或多个域模型存储库的数据存储项目。我对每一层的分离感到非常满意,但我坚持不知道从服务层返回到 Web 应用程序的内容。

例如,当用户尝试注册时,控制器会收到 RegisterViewModel。各个部分(电子邮件、密码等)被发送到服务层,该服务层使用 guid、状态、createdate 等构造成员域对象,将其发送到存储库进行存储,最后返回成员对象以供 Web 应用程序重定向到/成员/{guid}。

但是,如果电子邮件已存在,服务层应如何通知 Web 应用程序?在更复杂的情况下,我可能必须检查多个域对象和业务规则的存在/有效性,因此必须一次性返回多个错误。另外,我不希望异常冒泡到 Web 层,因此服务层会捕获所有异常,但需要以某种方式通知 Web 层。

即使我找到一种方法来返回所有这些,Web 层也将承担处理所有这些并为用户提供各种反馈的负担。控制器代码会很庞大并且错误会被删除。演示文稿的服务结果是否有最佳实践?我应该消除单独的服务层并将代码放在控制器内吗?欢迎任何想法。

Right now I have an ASP MVC web application along a Models project, a Service project, an Utilities project, and a few Datastores projects that function as repository for one or more domain models. I'm pretty happy with the separation of each layer but I'm stuck on what to return from service layer to the web app.

For example, when a user try to register, a RegisterViewModel is received by the controller. Individual pieces (email, password, etc.) are send to service layer which construct the Member domain object with guid, status, createdate, etc., send it to repository for storage and finally return the Member object for the web app to redirect to /Member/{guid}.

But how should the service layer inform the web app if an email already exists? In a more complex situation I may have to check the existence/validity of multiple domain objects and business rules so would have to return multiple errors in one go. In addition, I don't want exception to bubble to the web layer so service layer traps all exceptions but need to notify the web layer some how.

Even if I find a way to return all that, the web layer would be burdened to process all that and provide user various feedback. The controller code would be bulky and error prune. Is there a best practice on service result to the presentation? Should I eliminate separate service layer and have the code inside controller? Any thoughts are welcomed.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

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

发布评论

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

评论(2

妞丶爷亲个 2025-01-04 22:49:36

为此,我编写了 操作模型 库,它允许您编写如下代码:

public OperationResult Register(RegisterInput input) {

   var errors = new ErrorBuilder();

   if (errors.NotValid(input) // Invoke DataAnnotations validation
      || errors.Not(this.repo.FindUserByEmail(input.Email) == null, "Email '{0}' already exists.", () => input.Email))
      return errors;

   // Do stuff

   return HttpStatusCode.OK;
}

...并且在控制器中,错误消息被复制到 ModelState:

[HttpPost]
public ActionResult Register(RegisterInput input) {

   var result = this.service.Register(input);

   if (result.IsError)
      return View().WithErrors(result);

   // Do stuff
}

查看编写的 MvcAccount 项目的源代码使用这种模式。

I wrote the operation model library for this purpose, which allows you to write code like this:

public OperationResult Register(RegisterInput input) {

   var errors = new ErrorBuilder();

   if (errors.NotValid(input) // Invoke DataAnnotations validation
      || errors.Not(this.repo.FindUserByEmail(input.Email) == null, "Email '{0}' already exists.", () => input.Email))
      return errors;

   // Do stuff

   return HttpStatusCode.OK;
}

...and in the controller the error messages are copied to ModelState:

[HttpPost]
public ActionResult Register(RegisterInput input) {

   var result = this.service.Register(input);

   if (result.IsError)
      return View().WithErrors(result);

   // Do stuff
}

Check out the source code of the MvcAccount project which is written using this pattern.

简美 2025-01-04 22:49:36

首先,您需要决定是否为了分发目的而编写服务层。

如果您不打算将服务层分发到不同的进程/机器,

  1. 请创建消息类
  2. 创建消息类数组并将其存储在
    HttpContext.Items
  3. 现在,将任何层中的任何新消息添加到该数组中,
  4. 在视图/控制器中使用它。HttpContext.Items

在请求的生命周期内可用,您可以一直使用它直到视图。

如果您使用 DI 框架,则可以通过使用每个生命周期对象的请求来实现相同的目的。

如果您想分发对象,从服务层抛出异常没有任何问题。

First of all you need to decide if you are writing service layer for distribution purposes or not.

If you are not planning to distribute the service layer to a different process/machine,

  1. Create a Message class
  2. Create an array of message classes and store it in
    HttpContext.Items
  3. Now add any new message in any layer in to that array
  4. consume it in the views/controller

HttpContext.Items is available for the life time of the request and you can use it all the way up to views.

If you use a DI framework you can achieve the same by using a request per life time object.

If you want to distribute the object nothing wrong in throwing the exceptions from your service layer.

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