2011-02-27 6 views
1

나는 여기에 근본적인 것이 빠져 있다고 생각한다. 그러나 나는 두 시간 이상 파고 있었고 명백한 것을 간과해야만한다. 그렇다면 사과드립니다.서비스 확인은 컨트롤러로 어떻게 다시 전달됩니까?

나는 MVC 3 사이트를 가지고 있으며 내 컨트롤러와 통신하는 서비스 레이어와 서비스 레이어가 말하는 저장소 (IoC 컨테이너를 사용하여 모두 디커플링되었지만 여기서는 관련이 없다)가있다. 내 도메인 모델은 컨트롤러, 서비스 및 리포지토리간에 공유되는 EF4 엔터티입니다.

public class SignupViewModel 
{ 
    [DisplayName("Email")] 
    [Required, RegularExpression(@"^[email protected]+\..+$")] 
    public string Email { get; set; } 

    [DisplayName("Password")] 
    [Required] 
    public string Password { get; set; } 

    [DisplayName("Confirm password")] 
    [Required, Compare("Password")] 
    public string PasswordConfirmation { get; set; } 
} 

내 사용자의 도메인 모델은 다음과 같은 : :

public class User 
{ 
    public int Id { get; set; } 
    public string Email { get; set; } 
    public string PasswordHash { get; set; } 
    public string PasswordSalt { get; set; } 
} 

내가하는 데 사용되는 서비스 방법을

나는 이런 식으로 뭔가를 보이는 가입에 대한 뷰 모델을 가지고 다음과 같은 사용자를 등록하십시오.

public void Register(User user, string planTextPassword) 
{ 
    //Make sure the email address is not taken. 
    bool emailIsTaken = IsEmailTaken(user.Email); 

    if (emailIsTaken) 
    { 
     //What do I do here? 
    } 
    else 
    { 
     //Create the user. 
    } 
} 

그리고 마지막으로 내 컨트롤러 a ction 특 모두 함께 그것을 넥타이 :

내 서비스 방법에서 주석에서 볼 수 있듯이
public ActionResult Signup(SignupViewModel signupViewModel) 
{ 
    if (ModelState.IsValid) 
    { 
     _accountService.Register(Mapper.Map<SignupViewModel, User>(signupViewModel), signupViewModel.Password); 
     _unitOfWork.Commit(); 
    } 

    return View(signupViewModel); 
} 

, 서비스 수준 검증이 실패했을 경우 어떻게해야합니까? this question에서 논의했듯이 예외를 던져서는 안됩니다. 그러나 Ryan이 제안하는 내용을 따르는 지, 또는 여전히 적용 가능한지 (예 : 현재 MVC 3 또는 Fluent Validation과 같은 다른 도구로 처리 할 수있는 더 나은 방법이 있는지) 확실하지 않습니다.

내가 말했듯이, 나는이 시점에서 나무를위한 숲을 볼 수는 없다고 생각하지만 마지막 2 ~ 3 시간을 혼자서 알아 내려고 노력하면서 나는 더 나은 행운을 가질 것이라고 생각했다. 그냥 질문을.

미리 감사드립니다.

답변

2

한 번 Ryan이 이야기하는 것을하려고했습니다.

public class TheService{ 
    ValidationResult Validate(YourType item); 
    Save(YourType item); 
} 

사용법 먼저 유효성 검사를 호출하는 것입니다 및 모든 ValidationResult이 성공하면 저장을 호출 그가 말하는 것은 서비스가 다음과 같이 보일 것이 기본적이다. Save는 엔터티의 유효성을 다시 확인하여 유효성을 확인하는 것을 잊지 않고 있는지 확인합니다. 차이점은 저장 호출 유효성 검사 예외가 throw 될 때 오류가있는 경우입니다.

개인적으로 나는 이런 식으로 한 번하고 다시하지 않을 것입니다. 예외를 던지면 모든 것이 훨씬 명확 해지고 유지 관리하는 코드가 줄어 듭니다.

컨트롤러에 오류 정보를 다시 받으려면 사용자 자신의 예외를 만들어야합니다. 다음과 같이 표시 될 수 있습니다.

public class RulesException : Exception{ 
    public IEnumerable<ErrorInfo> Errors {get;set;} 
} 

public class ErrorInfo{ 
    public string PropertyName {get;set;} 
    public string ErrorMessage {get;set;} 
} 

그 라인에있는 것이 시작입니다. 더 나은 구현을 위해 소스 코드에서 xVal을 찾으십시오.

참고 : 예외를 사용하여 이동하려는 경우 루프 내에서 try/catch를 수행하는 코드를 작성하지 마십시오. 그것은 비용이 많이 들지만 예를 들어 데이터베이스 호출과 비교할 때 값이 싸기 때문에 예외가 발생할 때 피하는 것이 가장 중요합니다.

+0

좋은 답변입니다. 두 가지 접근법을 모두 시도한 사람의 의견을 듣는 것이 좋았으며 샘플이 확실히 도움이 될 것입니다. –

1

예외를 사용하지 않으려면 서비스 메서드가 일종의 풍부한 오류 메시지 개체를 반환하도록하는 것 외에 다른 옵션이 없습니다. 링크 된 게시물의 주장 중에서 강하게 동의하는 유일한 것은 예외 (자체적으로)가 좋은 오류 메시지를 초래할 가능성이 없다는 것입니다. 그들이 그 (것)들을 위해가는 것은 무시하는 것이 어렵다이다, 그래서 당신은 문제가 있다는 것을 깨닫게 될 것이다.

또한 예외를 처리해야하는 이유는 서비스 코드에서 완전히 피할 수 있다고하더라도 코드가 예외를 throw 할 수있는 유일한 것이 아니기 때문입니다.

즉 Register에 void 반환 형식이있는 대신 성공 또는 실패를 나타내는 클래스의 인스턴스를 반환 할 수 있으며 오류의 경우 오류를 나열하는 다른 속성이있을 수 있습니다. 이것은 원칙적으로 할 일입니다. 예를 들어 Haskell과 같은 언어에서는 매우 일반적입니다.

관련 문제