2009-09-21 4 views
4

페이지에서 드롭 다운 등의 엔티티를 선택할 수 있도록하려는 경우 Product라고 가정 해 보겠습니다.내 ASP.NET MVC 엔티티 바인딩 사용자 정의 : 좋은 해결책입니까?

public ActionResult SelectedAction(Product product) 
{ 
    if (ModelState.IsValid) {} else {} 
} 

내 모델 바인더를 사용하는 대신 저장소에서 내 제품을 얻을하고 난 모델 바인더 전원을 사용하려면, 그래서 대신 내가 모델 바인더를 쓰기

public ActionResult SelectedAction(Guid productId) 
{ 
} 

을하지만 : 결과적으로 나는이 나타날 수 있습니다 제품이 유효하지 않은 경우 모델 상태를 false로 설정합니다. 이제이이 방법 나왔습니다 문제 :

  1. 그것은 항상 Html.ActionLink와 같은 강력한 형식의 방법을 사용하는 것이 쉬운 일이 아니다 (C => c.SelectedAction (ID)) 우리는 제품을하지 통과해야하기 때문에 신분증.
  2. 어쨌든 엔티티를 컨트롤러 매개 변수로 사용하는 것은 좋지 않습니다.
  3. 모델 상태가 유효하지 않으며 다시 리디렉션하고 오류를 표시하려면 선택한 제품을 보존 할 수 없습니다! 바인딩 된 제품이 설정되어 있지 않으므로 내 ID가 없습니다. RedirectToAction (c => c.Redisplay (product))을하고 싶습니다. 물론 이것은 불가능합니다.

이제 "Guid productId"를 매개 변수로 사용하는 것처럼 보입니다 ... 그러나 제시하고 싶은 한 가지 해결책이 있습니다. 이제

public class EntityViewModel<T> where T : BaseEntity 
    { 
     public EntityViewModel(Guid id) 
     { 
     this.Id = id; 
     } 

     public static implicit operator EntityViewModel<T>(T entity) 
     { 
     return new EntityViewModel<T>(entity.Id); 
     } 

     public override string ToString() 
     { 
     return Id.ToString(); 
     } 

     public Guid Id { get; set; } 
     public T Instance { get; set; } 
    } 

, 내가

public ActionResult SelectedAction(EntityViewModel<Product> product) 
{ 
    if (ModelState.IsValid) {} else {} 
} 

모든 문제가 해결됩니다 사용하는 경우는 :

  1. 나는 단지 이드가있는 경우 설정 한 경우에만 아이디와 EntityViewModel를 전달할 수 있습니다.
  2. 매개 변수로 엔티티를 사용하지 않습니다. 또한 은 EntityViewModel을 다른 ViewModel 내부의 속성으로 사용할 수 있습니다.
  3. 다시 EntityViewModel을 RedirectToController에 전달할 수 있으며 유효성 검사 메시지 (MVCContrib 및 ModelStateToTempData/PassParametersDuringRedirect 덕분에)와 함께 사용자에게 이 다시 표시되는 Id 값을 유지합니다.

모델 바인더는 저장소에서 인스턴스를 가져오고 "데이터베이스에서 찾을 수 없음"과 같은 모델 상태 오류를 설정합니다. ActionLink (c => c.Action (Model.MyProductViewModelProperty))와 같은 것을 사용할 수 있습니다.

질문은 여기에 어떤 단점이 있습니까? 나쁜 것을 볼 수는 없지만 MVC를 처음 접했을 때 중요한 몇 가지 사항을 놓칠 수 있습니다. 어쩌면 더 좋고 승인 된 방법이 있을까요? 아마도 이것이 모두가 입력 매개 변수 및 속성으로 엔티티 ID를 사용하는 이유 일 수 있습니다. 당신이 당신의 ViewModel에 대한 POCO를 사용할 수 나에게 좋은 appoach처럼 보이는

+1

+1 흥미로운 접근 방식 ... –

+1

+1 괜찮은 접근 방식입니다. 나는 그것을 좋아한다. – grenade

답변

2

전체 ... 대안으로

, 그럼 내가 3 문제가 자동으로 해결 될 것이라고 생각합니다. Entity to DTO 접근법을 허용하는 Automapper 프로젝트를 보았습니까? 이렇게하면 EntityModel에서 ViewModel을 분리함으로써 더 많은 유연성을 얻을 수 있지만 실제로 구축중인 응용 프로그램의 복잡성에 따라 달라집니다.

MVC의 ViewDataExtensions는 대신 당신이 수에 언급 등 다양한 뷰 모델 객체를 보유하는 사용자 지정 컨테이너를 만드는 유용 할 수 있습니다 2. MVCContrib의 ModelStateToTempData가 (프로세스 sessionState의 공급자 중 어떤에 대한 직렬화해야합니다 직렬화 가능 객체에 대한 작업을해야

예를 들어 SQL, Velocity 등), 엔티티 클래스를 래핑하지 않고도 사용할 수 있습니다.

+0

내 엔티티는 POCO입니다. 1)에 대한 문제는 비즈니스 규칙이 항상 새로운 Entity (id)를 허용하지 않기 때문에 ActionLink에 의해 ID가 생성되고, 3) 입력/선택된 ID가 유효하지 않은 경우 (db가 아님), 엔티티를 리파지토리에서 가져 오면 null이 ModelStateToTempData를 통해 전달됩니다. 따라서 DTO에 Id와 Entity가 모두없는 경우 AutoMapper가 도움이되는 방법을 알지 못합니다. 엔티티가 이미 리포지토리에서 검색되도록하는 것이 목표이고, 실패하면 ID가 여전히 있음을 기억하십시오. ViewDataExtensions에 관해서는이 접근 방식을별로 좋아하지 않습니다. – queen3

+0

비즈니스 개체에 직접 바인딩하는 대신 프레젠테이션 모델을 사용하려고 생각했습니다. http://odetocode.com/Blogs/scott/archive/2009/04/05/12740.aspx,하지만 다른 아키텍처라고 생각합니다. 아이디어에 대한 직접적인 대안. ModelStateToTempData 문제의 경우 null 개체 패턴을 사용할 수 있지만 C# null 값을 반환하는 대신 요청한 ID를 속성으로 포함 할 수 있습니다. –

관련 문제