【问题标题】:Error handling MVC Views vs PartialView错误处理 MVC 视图与 PartialView
【发布时间】:2015-06-03 22:29:12
【问题描述】:

我已经阅读了很多关于 MVC 中错误处理的内容(特别是关于应用 HandleError 属性和关于在 Global.asax 上使用 Application_Error 的内容)。我有兴趣优雅地处理以下类型的异常:

  • 控制器内部抛出异常
  • 在视图中执行数据绑定时抛出异常。

目前我的应用程序的行为方式如下

  1. 控制器中抛出的所有异常都未处理。他们到达 Global.asax 的 Application_Error 方法
  2. 视图中的所有异常都未处理并到达 Global.asax 的 Application_Error 方法
  3. 在 Application_Error 方法中,我记录异常,确定应用程序是在本地运行还是远程运行。如果是这样,我会向用户显示黄屏,或者执行 Response.Redirect 到自定义错误页面。

此逻辑适用于呈现父视图或父视图本身的控制器内部引发的错误。这种逻辑的缺点是,当在应该呈现 PartialView 的子操作中引发错误时,整个页面将变得不可用。这是因为黄色错误屏幕或自定义错误页面占据了整个页面,不允许用户查看网页的其他部分。

我想做/知道的是是否有可能:

  1. 在局部视图内显示黄色错误屏幕,但正确呈现页面的其余部分。
  2. 将用户重定向到部分视图错误页面,从而使页面的其余部分保持可用。

【问题讨论】:

  • 我得到了类似的设置,从未遇到任何问题。我们使用局部视图。很想知道您是否可以提供一个示例代码,我可以在此处使用我的设置进行测试“当在应该呈现 PartialView 的子操作中引发错误时,整个页面变得不可用。”?
  • 我认为您可以在设置中看到答案,global.asax 对应用程序来说是全局的,如果您想处理应用程序内部的错误,您需要更改应用程序设置,并设置一个错误页面,它使用您的母版页并将其插入一个位置,具体取决于您希望客户端访问的内容。您可以有一个呈现消息等的局部视图......
  • @SBirthare 只需在控制器操作或局部视图中的任何位置添加throw new Exception() 代码行,看看会发生什么。 @JackM 我已经准备好了。全局错误页面已经定义并且用户被重定向到它。所以,整个页面都被我的自定义屏幕取代了
  • 明天会尝试,但很确定它不是我们错过的那么不寻常的案例。我希望它能够被我现有的配置优雅地处理。
  • @LuisBecerril - 我签入了我的应用程序,我们优雅地处理了这种情况。我在答案中添加了信息。希望这会有所帮助。

标签: c# asp.net-mvc asp.net-mvc-4 error-handling exception-handling


【解决方案1】:

处理这种特殊情况:

"当在子动作中抛出错误时,应该呈现一个 PartialView 整个页面变得无法使用。”

您可以为“ajaxError”定义一个全局 Ajax 事件处理程序,以处理使用“@Html.Partial”调用的操作引发的异常。

除了处理“Application_Error”中的所有错误外,我们还在 _Layout.cshtml 中定义了以下全局处理程序。这基本上可以处理从 html 调用部分视图并且操作引发异常的情况。如果遇到错误,则会记录数据并显示 toastr 弹出消息。

_Layout.cshtml:

    //Ajax Global Event Loader
    globalVar: ajaxContainer = $('div[id=wrap]');
    $(document).bind("ajaxSend", function () {
        if ($('.k-loading-mask').is("visible") == false) {
            var loader = new ajaxLoader(ajaxContainer, { bgColor: '#fff', duration: 800, opacity: 0.3, classOveride: false });
        }
    }).bind("ajaxComplete", function () {
        if ($('div[class=ajax_overlay]').is(':visible') == true)
            $('div[class=ajax_overlay]').remove();
    }).bind("ajaxError", function (event, jqxhr, settings, thrownError) {
        //debugger;
        $('div[class=ajax_overlay]').remove();
        $('.k-loading-image').remove();
        if ((settings.url.indexOf('Notification/GetActiveNotificationByUserName') < 0)
            && (settings.url.indexOf('LogError/LogData') < 0)) {
            var errorData = 'URL: ' + settings.url + '; Type: ' + settings.type + '; Data: ' + settings.data + '; thrownError: ' + thrownError;
            var model = { errorData: errorData };

            $.ajax({
                url: '@Url.Action("LogData", "LogError")',
                contentType: 'application/json; charset=utf-8',
                type: 'POST',
                dataType: 'html',
                data: JSON.stringify(model)
            })
            .success(function (result) {
                $("div.overlay").hide();
            })
            .error(function (xhr, status) {
                $("div.overlay").hide();
                //alert(status);
            });

            // Set toastr for error notification and display error 1 at a time
            toastr.options.closeButton = true;
            toastr.options.positionClass = 'toast-top-full-width';
            toastr.options.showMethod = 'slideDown';
            toastr.options.hideMethod = 'slideUp';
            toastr.options.showDuration = '1000';
            toastr.options.hideDuration = '1';
            toastr.clear();
            toastr.error('Your request cannot be processed right now. Please try again later!');
        }

        $("div.overlay").hide();
    });

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-15
    • 2012-06-09
    • 1970-01-01
    • 1970-01-01
    • 2010-09-16
    相关资源
    最近更新 更多