Как вернуть JSON из фильтра HandleError? - PullRequest
11 голосов
/ 21 сентября 2008

aspnet mvc имеет фильтр HandleError, который будет возвращать представление при возникновении ошибки, но если при вызове действия JsonResult возникает ошибка, как я могу вернуть объект JSON, представляющий ошибку?

Я не хочу оборачивать код в каждом методе действия, который возвращает JsonResult, в попытку / отлов для его выполнения, я бы лучше сделал это, добавив атрибут HandleJsonError или используя существующий атрибут HandleError в необходимые методы действий.

Ответы [ 3 ]

10 голосов
/ 21 сентября 2008

Взгляните на реализацию HandleErrorAttribute в MVC. Возвращает ViewResult. Вы можете написать свою собственную версию (HandleJsonErrorAttribute), которая возвращает JsonResult.

7 голосов
/ 15 августа 2012

Короче говоря, путь может заключаться в расширении атрибута HandleErrorAttribute, например:

public class OncHandleErrorAttribute : HandleErrorAttribute
{
    public override void OnException(ExceptionContext context)
    {
        // Elmah-Log only handled exceptions
        if (context.ExceptionHandled)
            ErrorSignal.FromCurrentContext().Raise(context.Exception);

        if (context.HttpContext.Request.IsAjaxRequest())
        {
            // if request was an Ajax request, respond with json with Error field
            var jsonResult = new ErrorController { ControllerContext = context }.GetJsonError(context.Exception);
            jsonResult.ExecuteResult(context);
            context.ExceptionHandled = true;
        }
        else
        {
            // if not an ajax request, continue with logic implemented by MVC -> html error page
            base.OnException(context);
        }
    }
}

Удалите строку кода Elmah, если она вам не нужна. Я использую один из моих контроллеров для возврата json на основе ошибки и контекста. Вот образец:

    public class ErrorController : Controller
{
    public ActionResult GetJsonError(Exception ex)
    {
        var ticketId = Guid.NewGuid(); // Lets issue a ticket to show the user and have in the log

        Request.ServerVariables["TTicketID"] = ticketId.ToString(); // Elmah will show this in a nice table

        ErrorSignal.FromCurrentContext().Raise(ex); //ELMAH Signaling

        ex.Data.Add("TTicketID", ticketId.ToString()); // Trying to see where this one gets in Elmah

        return Json(new { Error = String.Format("Support ticket: {0}\r\n Error: {1}", ticketId, ex.ToString()) }, JsonRequestBehavior.AllowGet);
    }

Я добавил информацию о билете выше, вы можете проигнорировать это. Благодаря тому, как фильтр реализован (расширяет стандартное значение HandleErrorAttributes), мы можем удалить HandleErrorAttribute из глобальных фильтров:

    public class MvcApplication : System.Web.HttpApplication
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new GlobalAuthorise());
        filters.Add(new OncHandleErrorAttribute());
        //filters.Add(new HandleErrorAttribute());
    }

Это в основном так. Вы можете прочитать мою запись в блоге для получения более подробной информации, но для идеи, приведенной выше, должно хватить.

1 голос
/ 21 сентября 2008

Возможно, вы могли бы создать свой собственный Атрибут и иметь значение конструктора, которое принимает значение перечисления View или Json. Ниже показано, что я использую для пользовательского атрибута авторизации, чтобы продемонстрировать, что я имею в виду. Таким образом, когда аутентификация завершается неудачно для запроса json, он отвечает ошибкой json и таким же образом, если он возвращает представление.

   public enum ActionResultTypes
   {
       View,
       Json
   }

    public sealed class AuthorizationRequiredAttribute : ActionFilterAttribute, IAuthorizationFilter
    {
        public ActionResultTypes ActionResultType { get; set; }

        public AuthorizationRequiredAttribute(ActionResultTypes actionResultType)
        {
            this.ActionResultType = ActionResultType;
        }
    }

    //And used like
    [AuthorizationRequired(ActionResultTypes.View)]
    public ActionResult About()
    {
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...