简体   繁体   中英

Error handling MVC Views vs PartialView

I have read a lot about error handling in MVC (specifically about applying a HandleError attribute and about using the Application_Error on the Global.asax). I am interested in gracefully handling the following types of exception:

  • Exceptions thrown inside the controller
  • Exceptions thrown when performing binding of data in the view.

Currently my application behaves in the following way

  1. All exceptions thrown in the controller are unhandled. They reach the Application_Error method of the Global.asax
  2. All exceptions in the view are unhandled and reach the Application_Error method of the Global.asax
  3. Once in the Application_Error method, I log the exception, decide if the application is run locally or remotely. If so, I present the yellow screen to the user, or perform a Response.Redirect to custom error pages.

This logic works correctly for errors thrown inside controllers that render parent views or the parent view itself. The downside of this logic is that, when an error is thrown inside a Child Action which should render a PartialView the whole page becomes unusable. This because the yellow error screen or the custom error page occupies the complete page and wont allow the user to view the other sections of the webpage.

What I want to do/know is if it is possible to:

  1. Display the yellow error screen inside of a partial view but render the rest of the page correctly.
  2. Redirecting the user to a partial view error page that allows for the rest of the page to remain usable.

To handle this specific case:

"when an error is thrown inside a Child Action which should render a PartialView the whole page becomes unusable."

You can define a global Ajax event handler for "ajaxError" to handle exception thrown from an action that is called using "@Html.Partial".

Apart from handling all errors in "Application_Error" we have defined following global handler in _Layout.cshtml. This basically handle cases where a partial view was invoked from html and the action threw an exception. If an error is encountered, data is logged and toastr popup message is displayed.

_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();
    });

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM