code

MVC, jQuery 및 오류 처리에 대한 모범 사례

starcafe 2023. 8. 16. 22:31
반응형

MVC, jQuery 및 오류 처리에 대한 모범 사례

ASP에서 오류를 처리하는 우아한 방법을 가진 사람이 있습니까?넷 MVC?일반 요청과 AJAX 요청 모두에 대해 Action을 사용할 수 있는 컨트롤러 작업에 대한 요청을 처리할 때 항상 문제가 발생합니다.제가 가진 문제는 이러한 문제들을 처리하는 우아한 방법을 찾는 것입니다.

예를 들어 유효성 검사 오류를 처리하려면 어떻게 해야 합니까?이상적으로는 AJAX를 통해 서버에 양식을 제출한 다음 작업에서 발생한 모든 오류를 반환하고 페이지에 표시하지만 클라이언트가 JavaScript를 해제했을 때 일반 포스트백을 통해 동일하게 작동하고 싶습니다.입력하는 대로 jQuery Validation Plugin을 사용할 수 있지만 동일하지 않으며, 유효성 검사할 데이터에 대한 제한이 두 곳(내 hibernate Validation Mappings 및 JavaScript 파일)에 지정된다는 점을 고려하면 이상적이지 않습니다.

사용자가 존재하지 않는 레코드를 요청할 때는 어떻습니까?404페이지로 수정해야 합니까?만약 Ajax를 통해 요청이 이루어졌다면(예: 대화 상자에 로드).

그래서:

Ajax를 사용하여 컨트롤러 작업이 호출되었을 때 발생한 오류를 어떻게 처리합니까?특히 모델 상태 오류(예: 검증).JSON으로 보내도 될까요?

Ajax를 통해 정상적으로 호출할 때 잘 작동하는 컨트롤러 작업을 만드는 방법에 대한 팁이 있습니까? 이것은 실행 방법을 작성할 때 성가신 문제입니다.반품 타입 때문에 저는 발신자에 따라 다른 결과를 원할 수도 있습니다.두 가지 실행 방법 없이 이 작업을 수행할 수 있는 방법이 있습니까?

MVC에서 작업 오류를 처리하기 위한 일반적인 전략은 무엇입니까?오류 페이지로 리디렉션하는 경우가 많습니까?다른 페이지로 리디렉션하시겠습니까?

편집: 문제의 일부는 다른 일이 일어나기를 바라는 것이라고 생각합니다. 따라서 오류가 발생하면 수정될 때까지 진행을 중지하고 오류를 반환합니다.그렇지 않으면 페이지의 다른 영역을 업데이트할 수 있습니다.그러나 만약 내가 하나의 반품을 가졌다면 그렇게 기소하는 속성을 가진 객체를 포장하지 않고 어떻게 그것이 성공인지 실패인지 알 수 있겠습니까(따라서 부분적인 견해를 사용하는 것을 더 어렵게 만듭니다).

감사해요.

AJAX 호출은 페이지 새로 고침이 아니므로 403, 404 등으로 리디렉션하지 않습니다.나는 요청의 예상치 못한 결과를 적절하게 설명하는 클라이언트 측 대화상자를 표시할 것입니다.컨트롤러는 성공 데이터를 반환하는 것과 유사한 방식으로 AJAX 호출에 실패한 유효성 검사 결과를 반환하여 이 시나리오에서 필요한 내용을 대화 상자에 표시할 수 있습니다.

Ajax를 통해 정상적으로 호출할 때 잘 작동하는 컨트롤러 작업을 만드는 방법에 대한 팁이 있습니까?이것은 실행 방법을 작성할 때 성가신 문제입니다.

네, 그렇습니다.우리는 또한 비슷한 문제를 해결했습니다. 우리는 앱이 일반적으로 Ajax를 통해 호출되지만 정상적으로 작동할 수 있는 여러 형태를 가지고 있기를 원했습니다.게다가, 우리는 자바스크립트의 중복된 논리들이 떠돌아다니는 것을 원하지 않았습니다.어쨌든, 우리가 생각해낸 기술은 한 쌍의 ActionFilterAttributes를 사용하여 양식을 가로채고, 약간의 Javascript를 사용하여 Ajax 처리를 위한 양식을 연결하는 것이었습니다.

먼저, Ajax 요청의 경우 마스터 페이지를 교환하고 싶었습니다.

    private readonly string masterToReplace;

    /// <summary>
    /// Initializes an Ajax Master Page Switcharoo
    /// </summary>
    /// <param name="ajaxMaster">Master page for ajax requests</param>
    public AjaxMasterPageInjectorAttribute(string ajaxMaster)
    {
        this.masterToReplace = ajaxMaster;
    }

    public override void OnResultExecuting(ResultExecutingContext filterContext)
    {
        if (!filterContext.HttpContext.Request.IsAjaxRequest() || !(filterContext.Result is ViewResult)) return;
        ViewResult vr = (ViewResult) filterContext.Result;
        vr.MasterName = masterToReplace;
    }
}

반환 측에서는 xVal을 사용하여 클라이언트 측의 유효성을 검사하므로 유효하지 않은 데이터를 방해하지는 않지만 일부 데이터는 얻을 수 있습니다.이를 위해 일반적인 유효성 검사를 사용하고 aciton 메서드가 유효성 검사 메시지와 함께 양식을 반환하도록 합니다.성공적인 게시물은 일반적으로 리디렉션으로 보상을 받습니다.어쨌든 성공 사례를 위해 약간의 json 주입을 합니다.

/// <summary>
/// Intercepts the response and stuffs in Json commands if the request is ajax and the request returns a RedirectToRoute result.
/// </summary>
public class JsonUpdateInterceptorAttribute : ActionFilterAttribute 
{
    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        if (filterContext.HttpContext.Request.IsAjaxRequest())
        {
            JsonResult jr = new JsonResult();
            if (filterContext.Result is RedirectResult)
            {
                RedirectResult rr = (RedirectResult) filterContext.Result;
                jr.Data = new {command = "redirect", content = rr.Url};
            }
            if (filterContext.Result is RedirectToRouteResult)
            {
                RedirectToRouteResult rrr = (RedirectToRouteResult) filterContext.Result;
                VirtualPathData vpd = RouteTable.Routes.GetVirtualPath(filterContext.RequestContext, rrr.RouteValues);
                jr.Data = new {command = "redirect", content = vpd.VirtualPath};
            }
            if (jr.Data != null)
            {
                filterContext.Result = jr;
            }
        }
    }
}

마지막 요령은 작은 자바스크립트 객체를 사용하여 모든 것을 하나로 묶는 것입니다.

function AjaxFormSwitcher(form, outputTarget, doValidation) {
    this.doValidation = doValidation;
    this.outputTarget = outputTarget;
    this.targetForm = form;
}

AjaxFormSwitcher.prototype.switchFormToAjax = function() {
    var afs = this;
    var opts = {
        beforeSubmit: this.doValidation ? afs.checkValidation : null,
        complete: function(xmlHttp, status){ afs.processResult(afs, xmlHttp, status); },
        clearForm: false
    };
    this.targetForm.ajaxForm(opts);
}

AjaxFormSwitcher.prototype.checkValidation = function(formData, jqForm, options) {
    jqForm.validate();
    return jqForm.valid();
}

AjaxFormSwitcher.prototype.processResult = function(afs, xmlHttp, status) {
    if (xmlHttp == null) return;
    var r = xmlHttp;
    var c = r.getResponseHeader("content-type");
    if (c.match("json") != null) {
        var json = eval("(" + r.responseText + ")");
        afs.processJsonRedirect(json);
    }
    if (c.match("html") != null) {
        afs.outputTarget.html(r.responseText);
    }
}

AjaxFormSwitcher.prototype.processJsonRedirect = function(data) {
    if (data!=null) {
        switch (data.command) {
            case 'redirect':
                window.location.href = data.content;
                break;
        }
    }
}

그 작은 스크립트는 폼을 연결하여 Ajax를 수행하고 결과를 처리하는 것과 같은 것을 처리합니다(대상에 표시되는 json 명령 또는 html).저는 자바스크립트를 쓰는 것을 확실히 못합니다. 그래서 아마도 그것을 쓰는 훨씬 더 우아한 방법이 있을 것입니다.

고지 사항:저는 ASP를 많이 하지 않았습니다.NET MVC 프로그래밍.

그렇긴 하지만, 저는 다른 언어로 된 MVC 프레임워크를 많이 사용했고, 장고 프로젝트를 꽤 많이 완료했습니다.시간이 지나면서, 저는 이런 종류의 장고를 다루는 패턴을 발전시켜 왔습니다. 템플릿 포함을 사용해서 말이죠.

기본적으로 양식(및 유효성 검사 오류)이 포함된 부분 템플릿을 생성합니다. 이 템플릿은 기본 템플릿에 포함됩니다.그런 다음 보기(또는 컨트롤러의 경우)는 다음 두 템플릿 중 하나를 선택합니다.AJAX 요청은 부분 템플릿을 가져오고, 일반 요청은 전체 템플릿을 가져옵니다.메인 템플릿에서 저는 JQuery 양식 플러그인을 사용하여 AJAX를 통해 양식을 제출하고 현재 양식을 서버의 데이터로 바꾸기만 하면 됩니다. 검증에 실패하면 필드가 강조 표시된 양식과 오류 목록이 상단에 표시됩니다. POST가 성공하면 양식이 성공 메시지로 바뀝니다.또는 당신의 상황에 더 적합한 것.

ASP에 있는 것 같아요.NET MVC 세계, 사용자 제어가 부분적인 것과 동등할 수 있습니까?이 기사는 제가 설명한 것과 유사한 것을 얻는 방법을 보여줍니다(그러나 기사는 다소 오래된 것으로 보이며 상황이 바뀔 수도 있었습니다).

두 번째 질문에 대답하자면, "페이지를 찾을 수 없습니다"에서 리디렉션을 수행하면 안 된다고 생각합니다. 하나는 302를 반환하고 다른 하나는 404를 반환해야 합니다. 하나는 오류 조건이 아닙니다. 다른 하나는 오류 조건이 아닙니다.상태 코드를 잃어버리면 자바스크립트가 더 복잡해집니다(실제 반환된 데이터를 어떻게든 테스트해야 무슨 일이 일어났는지 파악할 수 있기 때문입니다).이 두 게시물은 HTTP 친화적인 오류 페이지를 구현하는 방법에 대한 몇 가지 아이디어를 제공합니다.장고는 비슷한 일을 합니다. (a를 제기합니다.)Http404exception하고 선택적으로 상태 코드를 .404.html템플릿).

Ajax 및 일반 요청에 대한 작업 선택기 특성

하는 가장 은 사용자 속성Ajax 요청 일요구청가별방사좋것다입니는작하성속성을선기택지작업정과자)을 입니다.AjaxOnlyAtribute및의 상황을 하는 두 가지 및 각각의 상황을 처리하는 두 가지 작업 방법을 제공합니다.

[HttpPost]
[AjaxOnly]
[ActionName("Add")]
public ActionResult AddAjax(Entity data) { ... }

[HttpPost]
[ActionName("Add")]
public ActionResult AddNormal(Entity data) { ... }

이렇게 하면 코드 분기를 방지하고 코드 설치 공간을 작게 유지하면서 코드를 제어할 수 있습니다.쌍으로 구성된 작업을 필요로 하는 작업에만 제공합니다.

Ajax 요청의 유효성 검사 오류 처리

예외 작업 필터를 사용하여 Ajax 호출의 유효성 검사 오류(또는 기본적으로 다른 오류)를 처리할 수 있습니다.제가쓴 것중특히라는 .ModelStateExceptionAttribute다음과 같은 방식으로 수행됩니다.

[HandleModelStateException]
public ActionResult SomeAjaxAction(Data data)
{
    if (!this.ModelState.IsValid)
    {
        throw new ModelStateException(this.ModelState);
    }
    // usual code from here on
}

그리고 당신은 아마도 jQuery를 사용하여 Ajax 요청을 했을 것입니다. 그래서 이러한 오류는 오류 Ajax 함수에 의해 쉽게 처리됩니다.

$.ajax({
    type: "POST",
    url: "someURL",
    success: function(data, status, xhr) {
        // handle success
    },
    error: function(xhr, status, err) {
        // handle error
    }
});

여기에서 이 접근 방식에 대한 자세한 블로그 게시물을 읽을 수 있습니다.

우리는 절대 리디렉션하지 않습니다(사용자가 특정 필드에 입력해야 할 내용을 이해하지 못하는 경우에는 왜 '뒤로' 버튼을 반복적으로 누르도록 합니까?). AJAX든 아니든 간에 오류를 즉시 표시합니다(페이지의 '스폿' 위치는 전적으로 사용자에게 달려 있습니다. 모든 AJAX 요청에 대해서는 스택과 마찬가지로 페이지 상단에 색상이 표시됩니다.verflow는 선착순에게 적용되며, 우리의 것만이 나머지 콘텐츠를 밀어내지 않습니다.)

양식 유효성 검사의 경우 서버 측과 클라이언트 측을 모두 수행할 수 있습니다.우리는 항상 제출 시 해당 필드 바로 옆에 있는 고유 컨테이너인 클라이언트 측 양식 위에 서버 측 오류를 표시하려고 합니다.페이지가 서버에서 서버 측 유효성 검사 오류와 함께 돌아오면, 사용자는 서버 측 오류만 처음에 볼 수 있으므로 중복되지 않습니다.

두 곳에 지정된 데이터의 경우, 제가 nHibernate Validation Mappings를 다뤄본 적이 없기 때문에 제가 이해했는지 확실하지 않습니다.

두 개의 오류 보기를 유지합니다. 하나는 페이지의 일반(전체) 표시용이고 다른 하나는 XML 또는 JSON에서 오류를 렌더링하는 것입니다.

사용자가 쉽게 무시할 수 있으므로 클라이언트 측의 유효성을 검사하지 마십시오.실시간 유효성 검사를 위해 서버에 대한 AJAX 요청을 실행하면 유효성 검사 코드를 한 번 작성할 수 있습니다.

과거에 xVal을 자체 개발한 반사 기반 JS 규칙 생성기와 함께 사용한 적이 있습니다.즉, nHibernate를 통해 규칙을 한 번 정의하고 HTML 도우미가 속성을 반영하여 클라이언트 측 유효성 검사 코드를 즉시 생성합니다(jQuery.validation 플러그인 사용).서버 측 유효성 검사를 수행하면서 응답성이 뛰어난 클라이언트 측 UI를 사용할 수 있는 정확한 방법입니다.

안타깝게도 이 방법은 AJAX 게시 양식에 사용할 수 없습니다.

AJAX 규칙의 경우 반환된 JSON 개체에 오류 배열을 추가하기만 하면 됩니다.AJAX를 사용하는 곳이라면 어디서든 오류 길이(모두 모델 상태)를 확인하기만 하면 됩니다.IsValid(유효함)가 표시되고 오류가 표시됩니다.IsAjaxRequest 메서드를 사용하여 AJAX 호출을 검색할 수 있습니다.

public ActionResult PostForm(MyModel thing)
{
  UpdateModel(thing);

  if (this.Request.IsAjaxRequest() == false)
  {
    return View();
  }
  else
  {
    foreach(var error in ModelState.Errors)
    {
      MyJsonObject.Errors.Add(error.Message); 
    }
    return JsonResult(MyJsonObject);
  }
}

언급URL : https://stackoverflow.com/questions/1228379/best-practices-for-mvc-jquery-and-handling-errors

반응형