programing

MVC 컨트롤러에서 예외를 두지 않고 $.ajax에 오류를 보고하는 방법

stoneblock 2023. 3. 15. 17:47

MVC 컨트롤러에서 예외를 두지 않고 $.ajax에 오류를 보고하는 방법

컨트롤러와 정의된 방법을 가지고 있습니다.

[HttpPost]
public ActionResult UpdateUser(UserInformation model){

   // Instead of throwing exception
   throw new InvalidOperationException("Something went wrong");


   // I need something like 
   return ExecutionError("Error Message");

   // which should be received as an error to my 
   // $.ajax at client side...

}

예외에 관한 문제

  1. 디바이스 오류 또는 SQL Connectivity 오류와 같은 네트워크 오류가 발생할 경우 예외를 기록해야 합니다.
  2. 이러한 메시지는 사용자를 위한 검증 메시지와 같기 때문에 로그 기록하지 않습니다.
  3. 예외를 던지면 이벤트 뷰어도 플래딩됩니다.

클라이언트 측에서 오류가 발생할 수 있도록 $.ajax 콜에 커스텀 http 상태를 보고할 수 있는 쉬운 방법이 필요하지만 오류를 발생시키고 싶지 않습니다.

갱신하다

클라이언트 스크립트가 다른 데이터 소스와 일치하지 않기 때문에 변경할 수 없습니다.

현시점에서는 HttpStatusCodeResult가 동작하고 있습니다만, 여기서 문제가 발생하고 있는 것은 IIS입니다.어떤 에러 메시지를 설정해도, 모든 회신을 시도해도, 디폴트 메세지만 표시됩니다.

여기서 HTTP 상태 코드가 사용됩니다.Ajax를 사용하면 그에 맞게 대처할 수 있습니다.

[HttpPost]
public ActionResult UpdateUser(UserInformation model){
    if (!UserIsAuthorized())
        return new HttpStatusCodeResult(401, "Custom Error Message 1"); // Unauthorized
    if (!model.IsValid)
        return new HttpStatusCodeResult(400, "Custom Error Message 2"); // Bad Request
    // etc.
}

다음은 정의된 상태 코드 목록입니다.

묘사

오브젝트를 다시 페이지로 돌려보내서 분석하면 어떨까요?ajax콜백

샘플

[HttpPost]
public ActionResult UpdateUser(UserInformation model)
{
    if (SomethingWentWrong)
        return this.Json(new { success = false, message = "Uuups, something went wrong!" });

    return this.Json(new { success=true, message=string.Empty});
}

j쿼리

$.ajax({
  url: "...",
  success: function(data){
    if (!data.success) 
    {
       // do something to show the user something went wrong using data.message
    } else {
       // YES! 
    }
  }
});

커스텀 상태 코드를 사용하여 서버 오류를 반환하는 도우미 메서드를 기본 컨트롤러에 만들 수 있습니다.예:

public abstract class MyBaseController : Controller
{
    public EmptyResult ExecutionError(string message)
    {
        Response.StatusCode = 550;
        Response.Write(message);
        return new EmptyResult();
    }
}

필요에 따라 이 메서드를 액션으로 호출합니다.이 예에서는 다음과 같습니다.

[HttpPost]
public ActionResult UpdateUser(UserInformation model){

   // Instead of throwing exception
   // throw new InvalidOperationException("Something went wrong");


   // The thing you need is 
   return ExecutionError("Error Message");

   // which should be received as an error to my 
   // $.ajax at client side...

}

커스텀 코드 「550」을 포함한 에러는, 클라이언트측에서 다음과 같이 글로벌하게 처리할 수 있습니다.

$(document).ready(function () {
    $.ajaxSetup({
        error: function (x, e) {
            if (x.status == 0) {
                alert('You are offline!!\n Please Check Your Network.');
            } else if (x.status == 404) {
                alert('Requested URL not found.');
/*------>*/ } else if (x.status == 550) { // <----- THIS IS MY CUSTOM ERROR CODE
                alert(x.responseText);
            } else if (x.status == 500) {
                alert('Internel Server Error.');
            } else if (e == 'parsererror') {
                alert('Error.\nParsing JSON Request failed.');
            } else if (e == 'timeout') {
                alert('Request Time out.');
            } else {
                alert('Unknow Error.\n' + x.responseText);
            }
        }
    });
});

이것은 JSON으로서 Ajax 요청에 예외를 반송하는 것을 쓴 클래스입니다.

public class FormatExceptionAttribute : HandleErrorAttribute
    {
        public override void OnException(ExceptionContext filterContext)
        {
            if (filterContext.RequestContext.HttpContext.Request.IsAjaxRequest())
            {
                filterContext.Result = new JsonResult()
                                        {
                                            ContentType = "application/json",
                                            Data = new
                                                    {
                                                        name = filterContext.Exception.GetType().Name,
                                                        message = filterContext.Exception.Message,
                                                        callstack = filterContext.Exception.StackTrace
                                                    },
                                            JsonRequestBehavior = JsonRequestBehavior.AllowGet
                                        };

                filterContext.ExceptionHandled = true;
                filterContext.HttpContext.Response.StatusCode = 500;
                filterContext.HttpContext.Response.TrySkipIisCustomErrors = true; 
            }
            else
            {
                base.OnException(filterContext);
            }
        }
    }

다음과 같이 애플리케이션의 Global.asax.cs 파일에 MVC에 등록됩니다.

GlobalFilters.Filters.Add(new FormatExceptionAttribute());

Ajax 오류에 대해 이 특정 클래스를 사용합니다.

public class HttpStatusCodeResultWithJson : JsonResult
{
    private int _statusCode;
    private string _description;
    public HttpStatusCodeResultWithJson(int statusCode, string description = null)
    {
        _statusCode = statusCode;
        _description = description;
    }
    public override void ExecuteResult(ControllerContext context)
    {
        var httpContext = context.HttpContext;
        var response = httpContext.Response;
        response.StatusCode = _statusCode;
        response.StatusDescription = _description;
        base.JsonRequestBehavior = JsonRequestBehavior.AllowGet;
        base.ExecuteResult(context);
    }
}

상태 코드는 커스텀 HTTP 상태 코드이며 글로벌 Ajax 오류 함수에서 다음과 같이 테스트합니다.

MyNsp.ErrorAjax = function (xhr, st, str) {
        if (xhr.status == '418') {
            MyNsp.UI.Message("Warning: session expired!");
            return;
        }
        if (xhr.status == "419") {
            MyNsp.UI.Message("Security Token Missing");
            return;
        }
        var msg = 'Error: ' + (str ? str : xhr.statusText);
        MyNsp.UI.Message('Error. - status:' + st + "(" + msg + ")");
        return;
    };

내가 찾은 최선의 방법은 다음과 같다.

// Return error status and custom message as 'errorThrown' parameter of ajax request
return new HttpStatusCodeResult(400, "Ajax error test");

BigMike가 올린 글에 따르면 이것이 제가 NON MVC/WEBAPI 웹 프로젝트에서 했던 일입니다.

Response.ContentType = "application/json";
Response.StatusCode = 400;
Response.Write (ex.Message);

가치 있는 일(그리고 Big Mike에게 감사한다!)완벽하게 작동했다.

언급URL : https://stackoverflow.com/questions/8702103/how-to-report-error-to-ajax-without-throwing-exception-in-mvc-controller