【问题标题】:Is there any recommendation to bring up error messages from Data Access Layer to the view?是否有任何建议将错误消息从数据访问层显示到视图?
【发布时间】:2017-01-16 16:09:36
【问题描述】:

我想知道从数据访问层(或其他层)向视图显示错误消息的最佳实践或最佳/优雅方式。

我正在使用 ASP.NET MVC 5,我的项目有多个层,例如:

  • MyApp.Web
  • MyApp.Business
  • MyApp.Repository
  • MyApp.DAL

我想向 IHM 提出两种类型的“错误消息”:

  • 异常产生的错误:记录异常并显示人性化的错误消息。

  • 业务错误:例如,某项操作需要客户至少有 3 张发票,而他只有 2 张。

在另一个项目中,这是我所做的:

控制器

[HttpPost]
public ActionResult Edit()
{
    //...
    ErrorModel errorModel = new ErrorModel();

    BusinessLayer businessLayer = new businessLayer()
    businessLayer.Edit( /* some parameters */, out errorModel)

    TempData[Error] = errorModel
}

查看

@{
    var errorModel = TempData[Error]
}

/* if error model is not null, display the error correctly */

在每一层中,我所有的方法都有一个out ErrorModel 变量,它被填充在try / catch 块中,或者因为业务失败,我绝对不喜欢这样。

我在Google 或 Stack Overflow 上找到了很多答案,但都集中在如何捕获错误上。

*我的问题更进一步:一旦被捕获,如何以优雅的方式将错误从发生的层带到视图?

【问题讨论】:

    标签: asp.net-mvc error-handling architecture custom-error-handling


    【解决方案1】:

    一般方法是在所有层中抛出异常并在顶层处理它们(表示 - 控制器操作)。异常是一种方法结果,您不需要在方法签名中指定它。传递 errorModel 的方法不好,因为每个方法都应该返回它,每个方法都应该有 try catch 块。

    在业务层中,您可以拥有一些从 Exception 类派生的业务异常,并具有一些附加信息。或者您可以使用通用的 ApplicationException 类。
    所以,你的控制器看起来像

        [HttpPost]
        public ActionResult Edit()
        {
            try
            {
                businessLayer.Edit( /* some parameters */)
                return Ok();
            }
             catch(BadAcctionException)
            {
                TempData[Error] = "Bad business operation";
                return BadBusinessAction();
            }
            catch(ApplicationException ex)
            {
                TempData[Error] = ex.Message;
                return Fail();
            }
        }
    

    如果出现问题,在 businessLayer.Edit 内部会抛出异常。

    【讨论】:

    • 这看起来很有趣。因此,根据您的说法,我“仅”必须尝试/捕获所有层中的任何异常,然后在控制器中的“主要”尝试捕获中处理它们?
    • 仅在顶层(演示)尝试/捕获 - 处理错误。如果需要,您可以在其他层中抛出异常。
    • 如果您不想将某些异常暴露给顶层,您可以尝试/捕获较低层中的异常。例如,如果您不想将 DAL 中的 SqlConnectionException 传递给 Web 层,您可以尝试/在业务层中捕获此异常并在那里抛出类似 CriticalAppException 的东西
    • @VasylZvarydchuk 如果在您的 DAL 中,您在插入以共享相同的连接之前检查是否已经存在某些内容,并防止延迟关闭和重新打开。因此,在 DAL 中,您希望在某个时刻向视图传达数据库中已经存在的项目。这也算例外?
    猜你喜欢
    • 1970-01-01
    • 2012-09-07
    • 2014-03-04
    • 1970-01-01
    • 1970-01-01
    • 2016-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多