2009-12-10 5 views
9

이 오류는 이전에 클라이언트에 오류를 전달하는 중에 있었던 previous question까지 이어졌지 만 ModelState에도 해당됩니다.ASP.Net MVC에서 ModelState를 ajax 업데이트와 함께 사용할 수 있습니까?

Nerd Dinner 접근법을 성공적으로 사용해도 Ajax를 사용하는 사람이 있습니까? 그래서 괴상한 만찬은 그렇게 업데이트합니다. jQuery를 $ 아약스

function hijack(form, callback, errorFunction, format) { 
    $.ajax({ 
     url: form.action, 
     type: form.method, 
     dataType: format, 
     data: $(form).serialize(), 
     success: callback, 
     error: function(xhr, textStatus, errorThrown) { 
      errorFunction(xhr, textStatus, errorThrown); 
     } 
    }); 
} 

아약스, 컨트롤러의 "시도"일부

try 
{ 
    UpdateModel(dinner); 
    dinnerRepository.Save(); 
    return PartialView("PartialDetails", new { id=dinner.DinnerID }); 
} 

,하지만 당신은 캐치 부분에 대해 무엇을해야합니까하게 사용

[AcceptVerbs(HttpVerbs.Post)] 
    public ActionResult Edit(int id, FormCollection formValues) 
{ 
    Dinner dinner = dinnerRepository.GetDinner(id); 
    try 
    { 
     UpdateModel(dinner); 
     dinnerRepository.Save(); 
     return RedirectToAction("Details", new { id=dinner.DinnerID }); 
    } 
    catch 
    { 
     foreach (var issue in dinner.GetRuleViolations()) { 
     ModelState.AddModelError(issue.PropertyName, issue.ErrorMessage); 
    } 
     return View(dinner); 
    } 
} 

?

간단한 오류 처리 솔루션

오류가

catch(Exception ex) 
{ 
    Response.StatusCode = 500;     
    return Content("An Error occured."); 
    //throw ex; 
} 

것 다시 보낼 수 있지만, 는 MVC에 내장 된 강력한 modelstate을 통해를 전달하지 않습니다. 여러 가지 옵션을 생각했지만 실제로 2 가지를 원합니다.

  1. jQuery의 오류 속성에서 오류를 처리하기를 원합니다.
  2. 가능한 한 ASP.Net MVC 유효성 검사 로직을 내장하고 싶습니다.

이것이 가능합니까? 그렇지 않다면 가장 잘 알고있는 대안은 무엇입니까?

감사합니다.

업데이트 나는 아직까지 내가 가장 잘할 것이라고 생각하는 것을 구현하지 않았기 때문에 이것을 아직 답변하지 않았습니다.

내가 정말 성공을 같이 할 것을 결정했다 => 새로 고침 목록, 실패 => 내가 복용 한 오류 메시지의 접근 방식을 보내을 보낼 수 있습니다. 호출 횟수를 줄이기 위해이 작업을 수행했지만 새로 고침 된 목록이 실제로 페이지에 설정됩니다. 두 가지 모두 시도하면 팝업이 전체 페이지에 단단히 묶입니다.

대화 상자를 닫으면 사용자 정의 jQuery 이벤트를 추가하여 마스터 페이지 목록을 새로 고칩니다. 본질적으로 관찰자 패턴입니다. 나는 그 페이지가 왜 팝업을 말할 필요없이 팝업이 "끝났을 때 알려주세요"(일명 폐쇄)라고 말합니다. 추가 전화가 필요하지만 큰 문제로 보지 못합니다.

저는 서버 측 유효성 검사가 얼마나 좋고/싫어하는 지 아직 잘 모르겠습니다. 클라이언트 측 유효성 검사를 고려하고 있습니다.

1) 대신 처음에, 마지막에 품질 검사를 박았 : 서버 측 유효성 검사가 깨끗한 레이어처럼 보이지만, 그것은 또한 포함하여 많은 문제를 가지고 있습니다. 제조에 대한 비유는 딜러가 도착할 때 테스트되는 자동차가 될 것입니다.
2) Ajax의 의도를 위반합니다. Ajax는 비동기 이벤트를 전송하는 것이 아니라 필요한 것을 전송하고 필요한 정보만을받는 것입니다. 오류 세부 사항을 제공하기 위해 전체 modelstate를 보내면 Ajax와 관련없는 것처럼 보입니다.

내가하고있는 것에 대해 생각한 것은 클라이언트 측 유효성 검사 만 있지만 서버 코드와 사용자 지정 뷰 모델을 사용하여 클라이언트에게 유효성 검사 규칙을 동적으로 만드는 방법을 알릴 수 있습니다.

IronRuby 나 IronPython과 같은 동적 언어가 이러한 문제를 해결하는보다 우아한 방법을 제공 할 수도 있다고 생각하지만, 그 가능성을 조사하기 전에 조금 더 오래 걸릴 수 있습니다.

+0

글쎄, 정말 시나리오에 따라 다르다고 생각합니다. 2 요청을하면 문제가되지 않을 것입니다.개인적으로 클라이언트 측에서 JavaScript로 많은 유효성 검사를하는 것은 내가 좋아하는 것이 아닙니다 (왜 그런지 모르겠지만 js는 매우 신뢰할 수있는/안전하지 않은/똑같이 (이 jquery에서 하루 저장)), 특별히 때로는 클라이언트 측에서 모든 유효성 검사를 수행 할 수 없기 때문에 (이 엔티티는 이미 DB에 있습니까?) 일종의 서버 측 검사를 사용해야하며 js가 사용할 수없는 클라이언트를 지원하지만 처음에 말했듯이 시나리오에 따라 다릅니다. – JOBG

+0

나는 클라이언트 쪽에서 모든 유효성 검사를 할 수 없다는 것에 동의합니다. 유효성 검사 프레임 워크가 주로 필드 오류 (너무 길거나 날짜가 아님)쪽으로 조정 된 것처럼 보입니다. 최소한 내가 본 예에서. 사용자 입력을 검사 할 때 Javascript가 검사를 수행하기에 적절한 장소 인 것 같습니다. – John

+0

나는 하나의 전화가 아닌 2 개의 전화를하는 것에 대한 나의 결정을 확정했다. 나는 팝업이 "닫혀있다"는 페이지 뷰로 돌아가고 싶지만 페이지 뷰가 무엇을 할 것인지에 대해서는 알지 못한다. jQuery는 많은 노력 없이도이를 가능하게해야합니다. 따라서 내 세부 부분보기의 변경이 페이지에 영향을 미치고 그 반대의 경우도 마찬가지라는 걱정을하지 않아도됩니다. – John

답변

4

내가 무엇을하려고하는지 잘 이해한다면 나의 첫 번째 대답은 아니오가 될 것이며, 모델 상태는 Ajax 요청과 같이 사용할 수 없습니다. JSON에 의한 List<KeyValuePair<string,string>> (부동산, 메시지를) 전달

  1. (이것은 modelErrors이 새로운 구조에 modelState을 형성 통과하도록 요구합니다)와 수행 어쩌면 당신은 오류를 표시하려면 ModelState 동작을 에뮬레이트 할 수 있습니다 JS/jQuery에 의한 유효성 검사 요약 (Validation Summary)의 HTML 구성 (이는 내가 살인 솔루션 이상이라고 생각한다).

  2. 서버에 가서 오류가있는 경우 Html.ValidationSummary() 부분을 렌더링하고 JSON을 전달하여 양식 앞에 추가하십시오. 모든 것이 정상이면 PartialDetails 뷰를 반환하고 실제 내용을 바꿉니다. 어떤 종류의 상태 매개 변수가 필요하므로 ajax 콜백에서 서버로부터 무엇이 되돌아 오는지 알 수 있습니다.

편집 : 당신이 JSONResult에 의해 문자열 형태로 부분보기를 반환해야하므로이 마지막 옵션은 좋지만 까다로운 소리, 여기에이 Render a view as a string 해킹에 대한 질문 및 솔루션입니다.

개인적으로, 나는 오류 속성을 사용하는 것이 전혀 효과가 없을 것이라고 생각하지 않는다. 단지 예외 상황이 아닌 시간 초과 오류 및 서버 예외와 같은 매우 구체적인 상황에만 사용한다고 생각한다.

편집 : 당신이 각각의 경우에 수행 할 작업을 알려드립니다 다음 결과 매개 변수를

[AcceptVerbs(HttpVerbs.Post)] 
     public ActionResult Edit(int id, FormCollection formValues) 
     { 
      Dinner dinner = dinnerRepository.GetDinner(id); 
      try 
      { 
       UpdateModel(dinner); 
       dinnerRepository.Save(); 
       return Json(new 
       { 
        result = "success", 
        html = this.RenderToString("PartialDetails", dinner) 
       }); 

      } 
      catch 
      { 
       foreach (var issue in dinner.GetRuleViolations()) 
       { 
        ModelState.AddModelError(issue.PropertyName, issue.ErrorMessage); 
       } 
       return Json(new 
       { 
        result = "failed", 
        html = this.RenderToString("PartialEdit", dinner) 
       }); 
      } 
     } 

JSON

를 사용 , 그냥 콜백에 그것을 확인해야합니다.

+0

감사합니다. 그러나 도전 과제 중 하나는 JSON 결과가 아닌 PartialView 결과로 결과를 되돌려 보내고 싶다는 것입니다. 2. 전화 2 통화 중입니까? 하나는 성공/오류를 반환하고 다른 하나는 결과를 전달하는 것입니다. 그것이 내가 생각하고 있던 하나의 선택이다. – John

+0

{ "status": [{ "code": "error"}], "html": {{ "html": "많은 html"}}}과 같은 구조를 가진 정말 한 번의 호출. partialView Result 객체가되기를 원한다면 모델에 오류가있을 경우 부분 뷰 편집 구멍을 반환하지 않는 것이 좋습니다. 오류가 발생하지 않은 경우 세부 정보 부분보기를 사용하면 모델 상태가 아무런 문제없이 작동합니다. – JOBG

+0

대부분의 예제와 다른 시나리오를 만드는 부분은 성공 또는 오류 여부에 따라 두 가지 매우 다른 작업을 수행하려고한다는 것입니다. 오류 일 경우 편집 부분 뷰를 반환하고 대화 상자를 다시 만들 수 있습니다. 그러나 성공하면 대화 상자를 닫고 기본 페이지의 목록을 새로 고칩니다. 따라서 클라이언트 쪽 코드는 업데이트 할 개체 (대화 상자 또는 목록)를 알기 위해 성공/실패 여부를 알아야합니다. – John

2

MVC3에서 선호하는 접근 방식을 추가합니다. 당신의 편집 방법을 사용하면

[AcceptVerbs(HttpVerbs.Post)] 
public ActionResult Edit(int id, FormCollection formValues) 
{ 
    Dinner dinner = dinnerRepository.GetDinner(id); 
    try 
    { 
     UpdateModel(dinner); 
     dinnerRepository.Save(); 
     return Json (new { Success = true, Url = Url.Action("DetailsPartial", dinner), Div = "#DivToUpdateId" }); 
    } 
    catch 
    { 
     foreach (var issue in dinner.GetRuleViolations()) { 
     ModelState.AddModelError(issue.PropertyName, issue.ErrorMessage); 
    } 
     //I am replacing this with a partial view which will contain the model state errors. For people using MVC 3 with razor they should be able to use their normal views as partials 
     return PartialView(dinner); 
    } 
} 

뭔가를 할 수 있으며, 결과는 JSON 다음 data.Success에 해당하는 경우, 당신은, 그래서 기본적으로

success: function(data) { 
    if (data.Success) { 
     $.post(data.Url, function(partial) { 
      $(data.Div).html(partial); 
     }); 
    } 
    else 
    { 
     $('#formDiv').html(data) 
    } 
} 

같은 성공 기능을 사용할 수 있습니다. 그런 다음 json (data.Div)에 지정된 div를 URL에 지정된 작업 결과로 업데이트합니다. 결과가 Json 인 경우 post 메서드가 실패하고 formDiv가 ModelState 오류가 포함 된 부분 양식으로 업데이트됩니다. 이것은 대화 상자에서 사용하는 방법이지만 꽤 잘 작동합니다. MVC3을 사용하면 TryUpdateModel 등을 사용하는 것과 같은 편집 메서드를 일부 변경하지만 내 접근 방식의 예를 들어 보려고합니다. url을 전달하고 메소드의 결과를 게시하면 부분을 전달하기 위해 html을 문자열로 렌더링 할 필요가 없습니다.

+0

흥미 롭습니다. Edit PartialView에 대한 코드를 게시 할 수 있습니까? – John

관련 문제