自定义句柄异常不会返回我的自定义JSON

时间:2015-07-13 22:11:48

标签: javascript c# jquery asp.net asp.net-mvc

我有一个ASP.NET MVC应用程序,我实现了一个自定义HandleExceptionAttribute但是当app抛出一个ajax异常时,data.responseJSON没有任何JSON。

这是HandleExceptionAttribute

public class HandleExceptionAttribute : HandleErrorAttribute
{
    public override void OnException(ExceptionContext filterContext)
    {
        if (filterContext.HttpContext.Request.IsAjaxRequest() && filterContext.Exception != null)
        {
            Guid guid = Guid.NewGuid();
            string guidStr = guid.ToString();
            filterContext.HttpContext.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
            filterContext.Result = new JsonResult
            {
                JsonRequestBehavior = JsonRequestBehavior.AllowGet,
                Data = new
                {
                    success = false, 
                    error = "Error al procesar su solicitud, por favor comuniquese con un administrador con el siguiente codigo: " + guidStr,
                    StackTrace = filterContext.Exception.StackTrace
                }
            };
            filterContext.ExceptionHandled = true;

            var properties = new Dictionary<string, string> { { "Error GUID", guidStr } };
            var telemetry = new TelemetryClient();
            // Send the exception telemetry:
            telemetry.TrackException(filterContext.Exception, properties);
        }
        else
        {
            base.OnException(filterContext);
        }
    }
}

这是使用异常来显示错误的Javascript函数

function AddActividad() {
...
    $.ajax({
        url: 'IniciativasEstrategicasWebPart/AddActividad',
        type: 'POST',
        data: {
            idObjetivo: idObjetivoValue,
            IdIniciativa: idIniciativaValue,
            IniciativaName: iniciativaValue,
            Fase: fase,
            NombreActividad: nombreActividad,
            FechaInicio: fechaInicio,
            FechaVencimiento: fechaVencimiento,
            Estado: estado,
            Responsables: responsables
        }
    }).done(function (data) {
        DrawFasesInActividades(data);
    }).fail(function (data) {
        ShowErrorMessage(data);
    });
}
function ShowErrorMessage(data) {
    $("#divAlertIniciativas").attr("class", "alert alert-danger");
    $("#divAlertIniciativas").text(data.responseJSON.error);
    $("#alertIniciativasContainer").show("slow");
    location.href = "#alertIniciativasContainer"
    setTimeout(
        function () {
            $("#alertIniciativasContainer").hide("slow");
        }, 8000);
}

堆栈跟踪:

   at Microsoft.SharePoint.Client.ClientRequest.ProcessResponseStream(Stream responseStream)
   at Microsoft.SharePoint.Client.ClientRequest.ProcessResponse()
   at Microsoft.SharePoint.Client.ClientRequest.ExecuteQueryToServer(ChunkStringBuilder sb)
   at Microsoft.SharePoint.Client.ClientRequest.ExecuteQuery()
   at Microsoft.SharePoint.Client.ClientRuntimeContext.ExecuteQuery()
   at Microsoft.SharePoint.Client.ClientContext.ExecuteQuery()
   at business.businessbusiness.Controllers.IniciativasEstrategicasWebPartController.AddActividad(Actividad actividad) in d:\PC\business\Developers\Dev1\business\business\Controllers\businessWebPartController.cs:line 222
   at lambda_method(Closure , ControllerBase , Object[] )
   at System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters)
   at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters)
   at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters)
   at System.Web.Mvc.Async.AsyncControllerActionInvoker.ActionInvocation.InvokeSynchronousActionMethod()
   at System.Web.Mvc.Async.AsyncControllerActionInvoker.<BeginInvokeSynchronousActionMethod>b__39(IAsyncResult asyncResult, ActionInvocation innerInvokeState)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult`2.CallEndDelegate(IAsyncResult asyncResult)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.End()
   at System.Web.Mvc.Async.AsyncResultWrapper.End[TResult](IAsyncResult asyncResult, Object tag)
   at System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult)
   at System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3d()
   at System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.<>c__DisplayClass46.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3f()
   at System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.<>c__DisplayClass46.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3f()
   at System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.<>c__DisplayClass46.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3f()
   at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass33.<BeginInvokeActionMethodWithFilters>b__32(IAsyncResult asyncResult)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.End()
   at System.Web.Mvc.Async.AsyncResultWrapper.End[TResult](IAsyncResult asyncResult, Object tag)
   at System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethodWithFilters(IAsyncResult asyncResult)
   at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass21.<>c__DisplayClass2b.<BeginInvokeAction>b__1c()
   at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass21.<BeginInvokeAction>b__1e(IAsyncResult asyncResult)

2 个答案:

答案 0 :(得分:0)

我找到的解决方案是更改HandleExceptionAttribute并设置StatusDescription,因为filterContext.Result在某些情况下不起作用。

public class HandleExceptionAttribute : HandleErrorAttribute
{
    private bool IsAjax(ExceptionContext filterContext)
    {
        return filterContext.HttpContext.Request.Headers["X-Requested-With"] == "XMLHttpRequest";
    }
    public override void OnException(ExceptionContext filterContext)
    {
        if (filterContext.ExceptionHandled || !filterContext.HttpContext.IsCustomErrorEnabled)
        {
            return;
        }

        // if the request is AJAX return JSON else view.
        if (IsAjax(filterContext))
        {
            Guid guid = Guid.NewGuid();
            string guidStr = guid.ToString();
            filterContext.HttpContext.Response.Clear();
            filterContext.HttpContext.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
            filterContext.HttpContext.Response.StatusDescription = "Error al procesar su solicitud, por favor comuniquese con un administrador con el siguiente codigo: " + guidStr;
            filterContext.ExceptionHandled = true;

            var properties = new Dictionary<string, string> { { "Error GUID", guidStr } };
            var telemetry = new TelemetryClient();
            // Send the exception telemetry:
            telemetry.TrackException(filterContext.Exception, properties);
        }
        else
        {
            //Normal Exception
            //So let it handle by its default ways.
            base.OnException(filterContext);

        }
    }
}

答案 1 :(得分:0)

我有同样的问题。

添加filterContext.HttpContext.Response.TrySkipIisCustomErrors = true为我解决了这个问题。

所以在你的情况下:

public class HandleExceptionAttribute : HandleErrorAttribute
{
    public override void OnException(ExceptionContext filterContext)
    {
        if (filterContext.HttpContext.Request.IsAjaxRequest() && filterContext.Exception != null)
        {
            Guid guid = Guid.NewGuid();
            string guidStr = guid.ToString();
            filterContext.HttpContext.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
            filterContext.Result = new JsonResult
            {
                JsonRequestBehavior = JsonRequestBehavior.AllowGet,
                Data = new
                {
                    success = false, 
                    error = "Error al procesar su solicitud, por favor comuniquese con un administrador con el siguiente codigo: " + guidStr,
                    StackTrace = filterContext.Exception.StackTrace
                }
            };
            filterContext.ExceptionHandled = true;

            var properties = new Dictionary<string, string> { { "Error GUID", guidStr } };
            var telemetry = new TelemetryClient();
            // Send the exception telemetry:
            telemetry.TrackException(filterContext.Exception, properties);

            // Added this line
            filterContext.HttpContext.Response.TrySkipIisCustomErrors = true            
        }
        else
        {
            base.OnException(filterContext);
        }
    }
}