2010-06-10 3 views
0

나는 거의 문제없이 자신을 발견했으며, 사용자 정의 모델 바인더가 갈 길이라고 생각합니다.사용자 정의 모델 바인더, asp.net mvc 2 rtm 2, ComplexModel에 ID 구문 분석

내 도메인 모델은 다음과 같습니다. readly standard 페이지와 템플릿이 있습니다. Page는 템플릿을 참조로 사용합니다. 그래서 기본 asp.net mvc 바인더, 바인딩하는 방법을 알고, 따라서 나는 그것에 대한 몇 가지 규칙을 만들어야합니다. (사용자 정의 모델 바인더)

public class PageTemplate 
{ 
    public virtual string Title { get; set; } 
    public virtual string Content { get; set; } 
    public virtual DateTime? Created { get; set; } 
    public virtual DateTime? Modified { get; set; } 
} 



public class Page 
{ 
    public virtual string Title { get; set; } 
    public virtual PageTemplate Template { get; set; } 
    public virtual string Content { get; set; } 
    public virtual DateTime? Created { get; set; } 
    public virtual DateTime? Modified { get; set; } 
} 

그래서 나는 globals.asax에 ModelBinder를을 Registreted 한

ModelBinders.Binders.Add(typeof(Cms.Domain.Entities.Page), 
         new Cms.UI.Web.App.ModelBinders.PageModelBinder(
           new Services.GenericApplicationService<Cms.Domain.Entities.Page>().GetEntityStore() 
          ) 
         ); 

paremeter 다케 내 ModelBinder를이 마녀는 내 모든 엔티티를 얻을 내 저장소 (페이지 템플릿입니다)

페이지의 내 컨트롤러는 다음과 같습니다. 작성 컨트롤에 게시했습니다. Update 메소드 인 경우 지금은 중요하지 않습니다. 이 경우에는 템플릿을 나타내는 드롭 다운이 있으므로 양식 컬렉션에 ID가 표시됩니다.

다음 TryUpdateModel을 호출하면 내 PageModelBinder에서 히트가 발생합니다.

[AcceptVerbs(HttpVerbs.Post), ValidateAntiForgeryToken] 
[ValidateInput(false)] 
public ActionResult Create(FormCollection form) 
{ 
    Page o = new Page(); 

    string[] exclude = new { "Id" } 
    if (base.TryUpdateModel<Page>(o, string.Empty, null, exclude, form.ToValueProvider())) 
    { 
     if (ModelState.IsValid) 
     { 
      this.PageService.Add(o); 
      this.CmsViewData.PageList = this.PageService.List(); 
      this.CmsViewData.Messages.AddMessage("Page is updated.", MessageTypes.Succes); 
      return View("List", this.CmsViewData); 
     } 
    } 

    return View("New", this.CmsViewData); 
} 

그래서 모델 결합기로 끝납니다. 정보 검색을 위해 인터넷을 검색했지만 메신저 재고가 있습니다.

FormCollection에서 ID를 가져와 내 IEntityStore의 Model에서 구문 분석해야합니다. 하지만 어떻게?

public class PageModelBinder : IModelBinder 
{ 

    public readonly IEntityStore RepositoryResolver; 

    public PageModelBinder(IEntityStore repositoryResolver) 
    { 
     this.RepositoryResolver = repositoryResolver; 
    } 

    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) 
    { 
     if (bindingContext == null) 
     { 
      throw new ArgumentNullException("bindingContext"); 
     } 

     if (modelType == typeof(Cms.Domain.Entities.Page)) 
     { 
      // Do some magic 
      // Get the Id from Property and bind it to model, how ?? 
     } 
    } 

} 

// 데니스

나는 희망, 나의 problom은 분명하다.

답변

0

해결 방법을 찾았습니다. asp.net r2 rtm 2의 소스 코드를 다운로드했습니다.

기본 ModelBinder의 모든 코드를 복사하고 필요한 코드를 작성했습니다. 사소한 변화, 작은 해킹을 했습니까?

은 주변이 방법에 약간의 해킹을하고있는 작품은 :

[SuppressMessage("Microsoft.Globalization", "CA1304:SpecifyCultureInfo", MessageId = "System.Web.Mvc.ValueProviderResult.ConvertTo(System.Type)", 
     Justification = "The target object should make the correct culture determination, not this method.")] 
    [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", 
     Justification = "We're recording this exception so that we can act on it later.")] 
    private static object ConvertProviderResult(ModelStateDictionary modelState, string modelStateKey, ValueProviderResult valueProviderResult, Type destinationType) 
    { 
     try 
     { 
      object convertedValue = valueProviderResult.ConvertTo(destinationType); 
      return convertedValue; 
     } 
     catch (Exception ex) 
     { 
      try 
      { 
       // HACK if the binder still fails, try get the entity in db. 
       Services.GenericApplicationService<Cms.Domain.Entities.PageTemplate> repo; 
       repo = new Services.GenericApplicationService<Cms.Domain.Entities.PageTemplate>(); 
       int id = Convert.ToInt32(valueProviderResult.AttemptedValue); 
       object convertedValue = repo.Retrieve(id); 
       return convertedValue; 
      } 
      catch (Exception ex1) 
      { 
       modelState.AddModelError(modelStateKey, ex1); 
       return null; 
      } 
     } 
    } 

이 질문이 닫힙니다.