2012-09-28 6 views
0

viewmodel 속성의 일부인 복잡한 클래스가 있습니다. 내 viewmodel에는 와인 클래스 속성이 있고 와인 클래스에는 CaseProductions라는 ICollection 속성이 있습니다. CaseProduction 클래스에는 여러 속성이 있습니다.MVC 3 Completex IEnumerable이 포함 된 Viewmodel의 게시물

GET 이벤트 생성시 NewWineViewModel이 인스턴스화 된 다음 일부 기본값이 있지만 대부분 비어있는 CaseProduction 클래스 목록을 생성하여 GetCaseProductionDefaults를 실행합니다.

이제는 원래 foreach 문을 수행하고 원하는 방식으로 내 테이블을 튀어 나오기 위해 면도기를 사용했습니다. 하지만 그 주위에 POST에 대한 viewmodel 다시 IEnumerable이이 유형을 바인딩하려면 작동하지 않는 것을 보았다. 나는 아래 주사위를 사용하려했지만 주사위는 사용하지 않았다.

EditorFor(m => m.Wine.CaseProductions) 

나는 이것을 처리하는 가장 좋은 방법이 무엇인지에 대해 조언을 찾고 있습니다. 각각의 와인에는 케이스 제작 컬렉션이 있으며 뷰 모델 내 와인을 다시 바인딩해야합니다. 내가 묶는 지 확인하기 위해 면도날에있는 요소의 ID를 편집 할 수있는 방법이 있습니까? 이 것을 처리하는 가장 좋은 방법은 무엇입니까?

뷰 모델 :

public class NewWineViewModel 
    { 

     public Wine Wine { get; set; } 
     public VOAVIRequest VOAVIRequest { get; set; } 
     public bool IsRequest { get; set; } 

     public Dictionary<int, int> BottlesPerCase { get; set; } 
     public SelectList VarTypes { get; set; } 
     public SelectList Origins { get; set; } 
     public SelectList Apps { get; set; } 
     public SelectList Vintages { get; set; } 
     public SelectList Importers { get; set; } 
} 

경우 생산 클래스 :

public class CaseProduction 
{ 
    public int CaseProductionID { get; set; } 
    public int WineID { get; set; } 
    public int CaseProductionSizeID { get; set; } 
    public int CaseCount { get; set; } 
    public int CountPerCase { get; set; } 

    public virtual CaseProductionSize CaseProductionSize { get; set; } 
    public virtual Wine Wine { get; set; } 

} 

점점 기본 케이스 제작 :

public List<CaseProduction> GetCaseProductionDefaults(vfContext db) 
{ 
    //creates blank list of all formats 
    List<CaseProduction> cp = new List<CaseProduction>(); 
    foreach (CaseProductionSize size in db.CaseProductionSizes) 
    { 
     int defaultBottlesPerCase = 1; 
     switch ((CaseProductionSizeEnum)size.CaseProductionSizeID) 
     { 
      case CaseProductionSizeEnum.s187ml: 
       defaultBottlesPerCase= 24; 
       break; 
      case CaseProductionSizeEnum.s375ml: 
       defaultBottlesPerCase = 12; 
       break; 
      case CaseProductionSizeEnum.s500ml: 
       defaultBottlesPerCase = 12; 
       break; 
      case CaseProductionSizeEnum.s750ml: 
       defaultBottlesPerCase = 12; 
       break; 
      default: 
       defaultBottlesPerCase = 1; 
       break; 
     } 

     cp.Add(new CaseProduction { CaseProductionSizeID = size.CaseProductionSizeID, CountPerCase = defaultBottlesPerCase, CaseProductionSize = size, WineID = this.Wine.WineID }); 
    } 
    return cp; 
} 

경우 생산 테이블에 대한 내 면도기 코드 :

@foreach (vf2.Models.CaseProduction cp in Model.Wine.CaseProductions) 
      { 
       <tr> 
        <td>@cp.CaseProductionSize.Name 
        </td> 
        <td>@Html.Raw(@Html.TextBoxFor(m => m.Wine.CaseProductions.Where(c => c.CaseProductionSizeID == cp.CaseProductionSizeID).First().CaseCount, new { @class = "caseCount", id = "txt" + cp.CaseProductionSize.Name }).ToString().Replace("CaseCount","txt" + cp.CaseProductionSize.Name)) 
        </td> 
        <td> 
         @Html.DropDownListFor(m => m.Wine.CaseProductions.Where(c => c.CaseProductionSizeID == cp.CaseProductionSizeID).First().CountPerCase, new SelectList(Model.BottlesPerCase, "Key", "Value", cp.CountPerCase), new { @class = "countPerCase", id = "ddl" + cp.CaseProductionSize.Name, name = "ddl" + cp.CaseProductionSize.Name}) 
        </td> 
        <td class="totalBottleCalc"> 
        </td> 
       </tr> 
} 
내 caseproduction 수집

인스턴스 :

public ActionResult Create(int ID = 0, int VintUpID = 0) 
     { 
      NewWineViewModel nw = new NewWineViewModel(); 

      nw.Wine.CaseProductions = nw.GetCaseProductionDefaults(db); 
      nw.BottlesPerCase = nw.GetBottlesPerCase(db); 

답변

0

당신은 당신의 상위 모델 생성자에 중첩 된 목록 및 복잡한 모델을 인스턴스화해야합니다. 기본 모델 바인더는 하위 클래스를 인스턴스화하지 않습니다.

이렇게하면 EditorFor (m => m.Wine.CaseProductions)를 사용할 수 있으며 사용중인 복잡한보기 코드가 필요하지 않습니다.

CaseProduction을 렌더링하는 방법을 사용자 정의하려면 ~/Shared/EditorTemplates에 CaseProduction.cshtml 파일을 만들고이 정의를 사용하여 컬렉션의 각 항목을 렌더링합니다 (자동으로 당신을위한 컬렉션).

또한보기에서 linq 쿼리를 수행하지 않아야합니다. 문제는 데이터 엔터티를 뷰에 직접 전달하는 것처럼 보입니다. 이것은 나쁜 디자인입니다. 보기를 렌더링하는 데 필요한 정보 만 포함하는 ViewModel을 대신 만들어야합니다. 그런 다음 데이터를 View 모델에 할당하기 전에 필터링합니다.

0

CaseProduction 개체처럼 보이지 않기 때문에 모델 바인더가 CaseProduction 개체에서 픽업되지 않는다고 생각합니다. 당신은 CaseCount 이름을 바꾼

, 당신의 CaseProductionSize에는 ID가 없습니다 (없으며에게 CaseProduction을 수행하고, 여러 속성을 실종. 루프에서 당신이 그렇지 않으면. 모든 속성을 포함하고 포항 강판의 이름과 일치하는 이름을 유지해야 모델 바인더는 자신이 무엇인지 알지 못합니다. 원하는 경우 숨겨진 필드에 모든 속성을 넣을 수 있습니다.

관련 문제