使用异步方法进行错误处理和try / catch块

时间:2018-03-21 17:10:03

标签: asp.net-mvc async-await visual-studio-2017 try-catch asp.net-core-2.0

我正在Visual Studio 2017社区版中编写ASP.Net Core 2 MVC应用程序。我在理解try-catch块在处理异步方法时的行为方式时遇到了麻烦。下面是两个片段,一个控制器中的动作以及动作调用的方法。

首先让我说该计划按预期运作。问题是,当我故意创建一个错误时,我希望中间件显示预定的错误页面。这也适用于同一代码的同步版本。

使用此异步版本,浏览器不会返回任何错误,甚至不会返回HTTP500内部服务器错误页面,它只是在等待某些事情发生。如果我然后查看WebServer输出,我看到异常被抛出,我甚至读到错误页面视图已经运行,而实际上并非如此。

有人会善意解释我在这里缺少的东西吗?谢谢!

这是行动。我在方法中跳过了很多内容,因为它应该是无关紧要的,而且它真的很长。另外,我不认为它是相关的,但是我知道什么...所以请注意这个动作返回局部视图。该动作本身由另一个动作中的ajax请求调用。

     // Variance Report -- POST
     [HttpPost]
     [Authorize]
     [ValidateAntiForgeryToken]
     public async Task<IActionResult> Variance(VarianceModel model)
     {
         try
         {
             // Get the report data
             var varianceReport = await _report.GetVarianceReportAsync(model);

             // String that will display the current selection
             ViewBag.Parameters = model.parameterDescription;

             // Return the partial view
             return PartialView("_VariancePartial", varianceReport);
         }
         catch (Exception)
         {
             throw;
         }
     }

这是被调用的方法:

     // REPORT
     public async Task<VarianceModel> GetVarianceReportAsync(VarianceModel model)
     {
         try
         { 
             // Do a lot of stuff here... then I deliberately try to
             // divide by zero so as to get an error:
                         try
                         {
                             VariancePercent = (VarianceValue / 0)
                         }
                         catch (Exception)
                         {
                             throw;
                         }
             // Do more stuff here as well...
                 }
             return model;
         }
         catch (Exception)
         {
             throw;
         }
     }

最后,这是来自网络服务器的输出:

[...bla bla bla...]
WebApp> fail: Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware[0]
WebApp>       An unhandled exception has occurred: Attempted to divide by zero.
WebApp> System.DivideByZeroException: Attempted to divide by zero.
[...bla bla bla...]
WebApp> info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[1]
WebApp>       Executing action method WebApp.Controllers.HomeController.Error ( WebApp) with arguments ((null)) - ModelState is Valid
WebApp> info: 
Microsoft.AspNetCore.Mvc.ViewFeatures.Internal.ViewResultExecutor[1]
WebApp>       Executing ViewResult, running view at path /Views/Shared/Error.cshtml.
WebApp> info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[2]
WebApp>       Executed action WebApp.Controllers.HomeController.Error (WebApp) in 1.8921ms
WebApp> info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
WebApp>       Request finished in 66679.065ms 500 text/html; charset=utf-8

1 个答案:

答案 0 :(得分:0)

您正在抛出异常,但该页面无法找到它。 您应该返回一个实际的HTTP响应,而不仅仅是抛出异常:

[HttpPost]
[Authorize]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Variance(VarianceModel model)
{
    try
    {
        // Get the report data
        var varianceReport = await _report.GetVarianceReportAsync(model);

        // String that will display the current selection
        ViewBag.Parameters = model.parameterDescription;

        // Return the partial view
        return PartialView("_VariancePartial", varianceReport);
    }
    catch (Exception ex)
    {
        return new ObjectResult(ex);
    }
}

// REPORT
public async Task<VarianceModel> GetVarianceReportAsync(VarianceModel model)
{
    try
    {
        // divide by zero so as to get an error:
        VariancePercent = (VarianceValue / 0);
        return model;
    }
    catch (Exception)
    {
        throw;
    }
}

然而,这不是一个非常干净的回应。理想情况下,您应该为错误状态创建一个局部视图并返回:

public async Task<IActionResult> Variance(VarianceModel model)
{
    try
    {
        // Get the report data
        var varianceReport = await _report.GetVarianceReportAsync(model);

        // String that will display the current selection
        ViewBag.Parameters = model.parameterDescription;

        // Return the partial view
        return PartialView("_VariancePartial", varianceReport);
    }
    catch (Exception ex)
    {
        return PartialView("_ErrorPartial", ex);
    }
}
相关问题