2009-10-26 5 views
0

한다고 가정 나는이 모델이 : UserInput 사용자가 잘못되면 이제ASP.NET MVC는 : 사용자 입력 (복구)와 거래하고 결석 데이터 (복구 불능) 오류가

public class ViewModel 
{ 
    [Required] 
    public string UserInput { get; set; } 
    [Required] 
    public Guid EntityId { get; set; } 
} 

을, 나는 다시 표시 할 동일한 페이지이지만 유효성 검사 오류 (예 :/편집)가 있습니다. 그러나 EntityId가 틀리면 다른 페이지 (예 :/Create)로 리디렉션하려고합니다.

if (!ModelState.IsValidField("EntityId")) { redirect } 
//or 
if (string.IsNullOrEmpty(data.EntityId)) { redirect } 

내가 수동으로 각 컨트롤러 내에서이 작업을 수행 할 수

...하지만 그것은 종류의 지루 및 DRY 위반. 여러 엔티티 이미징, 엔티티가있는 중첩 된 뷰 모델 너무 복잡합니다. ModelState.IsValidUserData 및 ModelState.IsValidCriticalData와 같은 것을 사용하는 것이 좋습니다. 그러나 그런 것은 없습니다.

이제 EntityId는 실제로 내 맞춤 모델 바인더를 사용하여 바인딩됩니다. 은 업무상 중요한 것임을으로 알고 있습니다. 그래서이 해결책이 있습니다 :

  1. 일반적인 필드는 평소와 같이 ModelState를 오류로 채 웁니다.
  2. (a) 중요한 필드는 특수한 "CriticalModelErrorException"을 발생시키는 사용자 정의 모델 바인더를 사용하여 바인딩됩니다. 컨트롤러 액션에는 [HandleCrirticalError ("action", "controller ')] 속성이 있습니다. 중요한 오류를 처리하고 주어진 액션으로 리디렉션합니다. 모든 컨트롤러는 슈퍼 컨트롤러 기본 클래스에서 파생됩니다.) 각 액션은 ModelState.IsValid와 base.CriticalModelErrors 둘 다 자유롭게 검사 할 수 있으며이를 기반으로 자유롭게 동작합니다 ..
  3. (c) 중요한 필드는 특수 형식을 설정하는 사용자 정의 모델 바인더를 사용하여 바인딩됩니다. AddModelError (name, "! CRITICAL! text"; 그런 다음베이스 컨트롤러에 이러한 문자열을 감지하는 메서드가 있습니다.)

2a exa mple :

[HandleCriticalError("Create")] // uses the same controller 
[HandleModelStateError("Edit")] // redisplays page with validation errors 
public ActionResult Edit(ViewModel data) 
{ 
    // here we know both our data entities and user data are valid and safe 
} 

예 2b

public ActionResult Edit(ViewModel data) 
{ 
    if (!ModelState.IsValid) 
    return View(data); 
    if (base.CriticalModelErrors.Count > 0) 
    return RedirectToAction("Create"); 
    // here we know both our data entities and user data are valid and safe 
} 

2C 예 이제

protected bool HasCriticalErrors() 
{ 
    return ModelState.Any(x => x.Value.Errors.Any(x => x.ErrorMessage.StartsWith("!CRITICAL!"))) 
} 
// then same as 2b 

, 질문 :이 다른 응용 프로그램 개발자에 의해 처리 어떻게 (당신과 당신의 애플 리케이션)? 어느 것이 더 낫니? 결점이나 더 나은 해결책이 있습니까?

답변

1

대부분의 자동화가 인 을 소개하는 곳을 사용하면 내 장소에서 동일한 코드를 반복하지 않아도됩니다. 당신이 이미했듯이 2a으로 가고 싶지만 좀 다르게 만들어서 모든 싱글 액션에 대한 속성을 넣지 않고 전체 컨트롤러 클래스에 적용합니다. 가능하다면 (최소한 다수 행동으로 요구되는 경우). 특정 작업을 제외해야하는 경우 리디렉션을 사용할 수 없게하는 별도의 작업 필터를 만듭니다.