2009-08-26 4 views
2

훌륭한 MVC 책인 Steven Sanderson은 컨트롤러에서 데이터 저장 요소를 숨겨 세션 변수를 설정하고 검색하는 맞춤 모델 바인더의 예를 보여줍니다.세션에 저장된 객체에 대한 Sanderson의 맞춤 MVC ModelBinder 확장

꽤 일반적인 시나리오를 위해이 기능을 확장하려고합니다. 세션에 User 개체를 저장하고 모든 작업 메서드를 매개 변수로 사용할 수 있도록 만들고 있습니다. 사용자 세부 정보가 변경되지 않았을 때 Sanderson의 클래스는 정상적으로 작동했지만 사용자가 세부 정보를 수정하고 수정 된 개체를 다시 세션에 저장하도록해야합니다.

제 문제는 bindContext.ValueProvider.Keys의 키 수를 확인하는 것 이외의 다른 POST와 구별하는 방법을 찾지 못해서 이것이 잘못된 것이라고 생각합니다. 오해입니다. 어떤 것.

누구나 올바른 방향으로 나를 가리킬 수 있습니까? 기본적으로 모든 액션은 현재 사용자에게 액세스해야하며, UpdateMyDetails 액션은 동일한 객체를 업데이트해야합니다.이 모든 것은 모두 세션에 의해 지원됩니다. 여기에 내 코드 ...

public class CurrentUserModelBinder : IModelBinder 
{ 
    private const string userSessionKey = "_currentuser"; 
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { 
     var user = controllerContext.HttpContext.Session[userSessionKey]; 
     if (user == null) 
      throw new NullReferenceException("The CurrentUser was requested from the CurrentUserModelBinder but no IUser was present in the Session."); 

     var currentUser = (CCL.IUser)user; 
     if (bindingContext.ValueProvider.Keys.Count > 3) 
     { 

      var firstName = GetValue<string>(bindingContext, "FirstName"); 
      if (string.IsNullOrEmpty(firstName)) 
       bindingContext.ModelState.AddModelError("FirstName", "Please tell us your first name."); 
      else 
       currentUser.FirstName = firstName; 

      var lastName = GetValue<string>(bindingContext, "LastName"); 
      if (string.IsNullOrEmpty(lastName)) 
       bindingContext.ModelState.AddModelError("LastName", "Please tell us your last name."); 
      else 
       currentUser.LastName = lastName; 

      if (bindingContext.ModelState.IsValid) 
       controllerContext.HttpContext.Session[userSessionKey] = currentUser; 

     } 
     return currentUser; 
    } 
    private T GetValue<T>(ModelBindingContext bindingContext, string key) 
    { 
     ValueProviderResult valueResult; 
     bindingContext.ValueProvider.TryGetValue(key, out valueResult); 
     bindingContext.ModelState.SetModelValue(key, valueResult); 
     return (T)valueResult.ConvertTo(typeof(T)); 
    } 
} 
+0

어디서 대답을 찾았습니까? 나는 똑같이해야한다. – longday

+0

나도 Steven Sanderson이 제안한 경로를 따라 갔지만 이제는 사용자 정의 모델 바인더에서 데이터 액세스에 대한 의견이 엇갈리고 있습니다. 내 의존성 삽입을 사용자 정의 모델 바인더에서 작동시키는 것처럼 보이지 않습니다. 분명히 당신은 커스텀 모델 바인더에서 IoC를 가질 수 없습니다 ... – autonomatt

답변

1

대신 IModelBinder의 DefaultModelBinder에서 상속 시도, 다음으로 MVC 2.0

에 대한 MVC 1.0 bindingContext.ModelMetadata.Model에 대한 bindingContext.Model을 채울 base.BindModel를 호출 할 수 있습니다입니다 bindingContext.Model을 트리거하여 컨트롤러에서 UpdateModel을 호출합니다.

당신은 모델을 채우고 세션에 저장

if(bindingContext.Model != null) 
throw new InvalidOperationException("Cannot update instances"); 

다시 책에서 문을 추가하지만, 그것을 변경해야합니다.

if(bindingContext.Model != null) 
{ 
    base.BindModel(controllerContext, bindingContext); 
    //save bindingContext.Model to session, overwriting current. 
    return bindingContext.Model 
}