【问题标题】:What to return from service to ASP MVC web app?从服务返回到 ASP MVC Web 应用程序的内容是什么?
【发布时间】:2012-02-18 07:24:23
【问题描述】:

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

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

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

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

【问题讨论】:

    标签: asp.net-mvc service-layer three-tier


    【解决方案1】:

    我为此编写了operation model 库,它允许您编写如下代码:

    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 项目的源代码。

    【讨论】:

    • 感谢您的代码。我可能会做这样的事情,但可能会为每个服务调用量身定制结果。
    【解决方案2】:

    首先,您需要确定您是否正在编写服务层以用于分发目的。

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

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

    HttpContext.Items 在请求的整个生命周期内都可用,您可以一直使用它直到视图。

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

    如果你想分发对象,从你的服务层抛出异常没有错。

    【讨论】:

    • 我不确定我是否希望我的服务层能够感知 HttpContext,但你确实给了我一种我以前没有想到的可能性。谢谢!
    • HttpContext.Items 只是一个在请求期间存在的容器。正如我在帖子中提到的,您可以使用任何容器。如果没有计划分发系统,为什么不使用httpcontext?
    猜你喜欢
    • 1970-01-01
    • 2011-01-13
    • 1970-01-01
    • 1970-01-01
    • 2019-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多