programing

부분 보기를 반환하는 Ajax 호출 컨트롤러 작업에서 모델 상태 오류를 처리하는 방법

oldcodes 2023. 7. 28. 22:36
반응형

부분 보기를 반환하는 Ajax 호출 컨트롤러 작업에서 모델 상태 오류를 처리하는 방법

부분 보기를 반환하는 POST 컨트롤러 작업이 있습니다.모든 것이 정말 쉬워 보이지만.를 사용하여 로드합니다.$.ajax()유형 설정html하지만 모델 유효성 검사에 실패하면 모델 상태 오류와 함께 오류를 발생시켜야 한다고 생각했습니다.하지만 내 답장은 항상 500 서버 오류를 반환합니다.

Json을 반환하지 않고 모델 상태 오류를 다시 보고하려면 어떻게 해야 합니까?HTML 요소에 직접 추가할 수 있는 부분 보기를 여전히 반환하고 싶습니다.

편집

또한 오류 부분 보기를 반환하지 않도록 하고 싶습니다.이것은 고객에게 성공적인 것처럼 보일 것입니다.고객이 결과를 분석하여 실제 성공 여부를 확인하도록 하면 오류가 발생하기 쉽습니다.설계자는 부분 뷰 출력을 변경할 수 있으며 이것만으로도 기능이 손상될 수 있습니다.그래서 나는 예외를 던지고 싶지만, 정확한 오류 메시지가 Ajax 클라이언트에 반환되었습니다.

해결책

저는 의도한 대로 자동으로 작동하는 두 부분을 따로 작성해야 했습니다.

따라서 컨트롤러 작업 프로세스가 성공할 때 부분 보기를 반환해야 하며, 문제가 해결되지 않을 때 일부 오류 세부 정보와 함께 오류를 발생시켜 항상 성공을 처리하는 대신 클라이언트 측에서 성공과 실패를 구분해야 합니다.

이를 위해 두 가지 주요 부분이 사용됩니다.

  • 문제가 발생할 때 던져지는 사용자 지정 예외 클래스로, 처리와 관련된 이유와 오류(가장 현저하게 잘못된 모델 상태)에 관계없이 언제든지 발생할 수 있는 일반 예외를 구별할 수 있습니다.
  • 사용자 지정 예외를 포착하고 해당 예외를 기반으로 결과를 준비하는 예외 작업 필터. 코드에서 알 수 있듯이 사용자 지정 예외는 모델 상태 오류에 대한 정보를 보유하므로 이 필터는 사용자 지정 HTTP 상태 코드와 일부 텍스트 정보를 반환할 수 있습니다.

그러면 자세한 내용은...

외부 링크:이 모든 정보(자세한 설명과 모든 코드)는 제 블로그에서도 확인할 수 있습니다.최신 코드 업데이트는 항상 여기에 게시됩니다.

사용자 지정 예외 클래스

이 수업은 두 가지를 제공합니다.

  1. 모형 상태 오류와 일반 예외를 쉽게 구별할 수 있도록 합니다.
  2. 나중에 사용할 수 있는 몇 가지 기본 기능 제공

이 클래스는 나중에 사용자 지정 오류 필터에서 사용됩니다.

public class ModelStateException : Exception
{
    public Dictionary<string, string> Errors { get; private set; }

    public ModelStateDictionary ModelState { get; private set; }

    public override string Message
    {
        get
        {
            if (this.Errors.Count > 0)
            {
                return this.Errors.First().Value;
            }
            return null;
        }
    }

    private ModelStateException()
    {
        this.Errors = new Dictionary<string, string>();
    }

    public ModelStateException(ModelStateDictionary modelState) : this()
    {
        this.ModelState = modelState;
        if (!modelState.IsValid)
        {
            foreach (KeyValuePair<string, ModelState> state in modelState)
            {
                if (state.Value.Errors.Count > 0)
                {
                    this.Errors.Add(state.Key, state.Value.Errors[0].ErrorMessage);
                }
            }
        }
    }
}

오류 필터 특성

이 속성은 모델 상태 오류가 있을 때 HTTP 오류 코드 측면에서 클라이언트에 오류를 반환하는 데 도움이 됩니다.

[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
public class HandleModelStateExceptionAttribute : FilterAttribute, IExceptionFilter
{
    public void OnException(ExceptionContext filterContext)
    {
        if (filterContext == null)
        {
            throw new ArgumentNullException("filterContext");
        }

        if (filterContext.Exception != null && typeof(ModelStateException).IsInstanceOfType(filterContext.Exception) && !filterContext.ExceptionHandled)
        {
            filterContext.ExceptionHandled = true;
            filterContext.HttpContext.Response.Clear();
            filterContext.HttpContext.Response.ContentEncoding = Encoding.UTF8;
            filterContext.HttpContext.Response.HeaderEncoding = Encoding.UTF8;
            filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
            filterContext.HttpContext.Response.StatusCode = 400;
            filterContext.HttpContext.Response.StatusDescription = (filterContext.Exception as ModelStateException).Message;
        }
    }
}

그 후, 저는 제 특성과 voila로 컨트롤러 동작을 장식했습니다.클라이언트에서 코드 400과 필터에 설정한 정보에 오류가 발생했습니다.그런 다음 이 정보가 사용자에게 표시됩니다(모델 상태 오류와 관련된 경우 사용자가 양식을 유효하게 만들기 위해 수정해야 하는 양식 필드 정보가 표시됩니다).

[HandleModelStateException]
public ActionResult AddComment(MyModel data)
{
    // check if state is valid
    if (!this.ModelState.IsValid)
    {
        throw new ModelStateException(this.ModelState);
    }
    // get data from store
    return PartialView("Comment", /* store data */ );
}

이렇게 하면 모델 상태 오류와 함께 코드가 재사용 가능하게 되고 오류는 클라이언트로 전송됩니다.

단일 문제(이제 해결됨)

하지만 아직 이 코드와 관련된 문제가 하나 있습니다.오류 작업 필터가 설정된 경우 StatusDescription그리고 그 문자열에는 CH와 같은 특수 문자가 포함되어 있습니다. 클라이언트에서 쓰레기가 나옵니다.IE를 사용하지 않는 한(저는 버전 8을 사용합니다).FF 및 CH는 쓰레기를 표시합니다.그래서 인코딩을 설정했는데 작동하지 않습니다.이 특수성에 대한 해결책이 있는 사람이 있다면 기꺼이 들어보겠습니다.
내용 자체에 오류 메시지가 표시되면 모든 것이 정상입니다.인코딩이 올바르고 원하는 대로 표시할 수 있습니다.

이거 먹어봐요.

public ActionResult DoAjaxAction(Entity entity)
{
   if(ModelState.IsValid)
   {
     return PartialView("Valid_View", entity);
   }
   else
   {
     return PartialView("Invalid_View", entity);
   } 

}

언급URL : https://stackoverflow.com/questions/2261617/how-to-handle-model-state-errors-in-ajax-invoked-controller-action-that-returns

반응형