2008-09-21 5 views
9

aspnet mvc에는 오류가 발생하면보기를 반환하는 HandleError 필터가 있지만 JsonResult Action을 호출 할 때 오류가 발생하면 어떻게 오류를 나타내는 JSON 객체를 반환 할 수 있습니까?HandleError 필터에서 JSON을 반환하는 방법은 무엇입니까?

try/catch에서 JsonResult를 반환하는 각 동작 메서드에 코드를 래핑하고 싶지 않습니다. 대신 HandleJsonError 특성을 추가하거나 기존 HandleError 특성을 사용하여 코드를 수행 할 수 있습니다. 필요한 조치 방법.

답변

9

HandleErrorAttribute의 MVC 구현을 살펴보십시오. ViewResult를 반환합니다. JsonResult를 반환하는 자신 만의 버전 (HandleJsonErrorAttribute)을 작성할 수 있습니다.

+0

나는 이것을 시도했지만 HandleJsonErrorAttribute OnException 메서드를 호출 할 때 action이 속한 Controller 클래스의 HandleErrorAttribute가 true 일 때 filterContext.ExceptionHandled 속성은 항상 true입니다. 액션 메소드 handleerror가 우선시되고 먼저 호출되어야하지 않습니까? –

1

아마도 자신의 Attribute를 만들고 View 또는 Json의 enum 값을 취하는 생성자 값을 가질 수 있습니다. 다음은 사용자 정의 권한 부여 속성에 대해 의미하는 바를 보여주기 위해 사용하는 Im입니다. 이렇게하면 json 요청에서 인증이 실패 할 때 json 오류로 응답하고 View가 반환하면 응답합니다.

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() 
    { 
    } 
+0

나는 실제 예제를 구현하려고합니다. 당신이 그것이 나던 일을 찾거나 다른 해결책을 찾으면 알려주세요! – Vyrotek

7

즉, 이동하는 방법이처럼 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()); 
    } 

이 기본적이다. 더 자세한 정보는 my blog entry을 읽을 수 있지만 위의 아이디어로 충분합니다.

+2

위는 IISExpress에서 개발하는 동안 작동합니다. 이 기능을 실제 IIS 웹 서버에 배포 할 때 jsonmessage를 IIS otherwize로 만들 때'context.HttpContext.Response.TrySkipIisCustomErrors = true; '를 추가해야 오류 메시지가 무시되고 기본 상태 코드 500 페이지가 표시됩니다 – mortb

관련 문제