2011-07-05 32 views
30

Tôi có một ViewModel cơ bản với thuộc tính là Danh sách các loại phức tạp. Khi ràng buộc, tôi dường như bị mắc kẹt khi nhận danh sách giá trị HOẶC các thuộc tính mô hình khác tùy thuộc vào giá trị được đăng (tức là sắp xếp xem).MVC ràng buộc với mô hình có thuộc tính danh sách bỏ qua các thuộc tính khác

Mô hình xem:

public class MyViewModel 
{ 
    public int Id { get; set; } 
    public string Property1 { get; set; } 
    public string Property2 { get; set; } 

    public List<MyDataItem> Data { get; set; } 
} 

public class MyDataItem 
{ 
    public int Id { get; set; } 
    public int ParentId { get; set; } 
    public string Name { get; set; } 
    public string Value { get; set; } 
} 

Những hành động điều khiển:

public ActionResult MyForm() 
    { 
     MyViewModel model = new MyViewModel(); 

     model.Id = 1; 
     model.Data = new List<MyDataItem>() 
     { 
      new MyDataItem{ Id = 1, ParentId = 1, Name = "MyListItem1", Value = "SomeValue"} 
     }; 

     return View(model); 
    } 

    [HttpPost] 
    public ActionResult MyForm(MyViewModel model) 
    { 
     //... 

     return View(model); 
    } 

Đây là quan điểm cơ bản (không có trong danh sách mark-up)

@using (Html.BeginForm()) { 
    @Html.ValidationSummary(true) 
    <fieldset> 
     <legend>My View Model</legend> 

     @Html.HiddenFor(model => model.Id) 

     <div class="editor-label"> 
      @Html.LabelFor(model => model.Property1) 
     </div> 
     <div class="editor-field"> 
      @Html.EditorFor(model => model.Property1) 
      @Html.ValidationMessageFor(model => model.Property1) 
     </div> 

     <div class="editor-label"> 
      @Html.LabelFor(model => model.Property2) 
     </div> 
     <div class="editor-field"> 
      @Html.EditorFor(model => model.Property2) 
      @Html.ValidationMessageFor(model => model.Property2) 
     </div> 

     <p> 
      <input type="submit" value="Save" /> 
     </p> 
    </fieldset> 
} 

Khi đăng lại để bộ điều khiển, tôi nhận được 2 giá trị thuộc tính và giá trị null cho thuộc tính 'Dữ liệu' như mong đợi.

Without List Mark-up

Nếu tôi thêm các dấu-up cho danh sách như sau (dựa trên thông tin trong Scott Hanselman post này và Phil Haack's post):

<div class="editor-field"> 
@for (int i = 0; i < Model.Data.Count(); i++) 
{ 
    MyDataItem data = Model.Data[i]; 
    @Html.Hidden("model.Data[" + i + "].Id", data.Id) 
    @Html.Hidden("model.Data[" + i + "].ParentId", data.ParentId) 
    @Html.Hidden("model.Data[" + i + "].Name", data.Name) 
    @Html.TextBox("model.Data[" + i + "].Value", data.Value) 
} 
</div> 

Thuộc tính 'dữ liệu' của mô hình là thành công bị ràng buộc nhưng các thuộc tính khác là null.

With List Mark-up

Các giá trị hình thức đăng tải như sau:

Id=1&Property1=test1&Property2=test2&model.Data%5B0%5D.Id=1&model.Data%5B0%5D.ParentId=1&model.Data%5B0%5D.Name=MyListItem1&model.Data%5B0%5D.Value=SomeValue 

Có cách nào để có được cả hai bộ tài sản dân cư hay tôi chỉ còn thiếu một cái gì đó rõ ràng?

EDIT:

Đối với những người bạn của những người tò mò. Dựa trên câu trả lời từ MartinHN, bản gốc được tạo ra mark-up là:

<div class="editor-field"> 
    <input id="model_Data_0__Id" name="model.Data[0].Id" type="hidden" value="1" /> 
    <input id="model_Data_0__ParentId" name="model.Data[0].ParentId" type="hidden" value="1" /> 
    <input id="model_Data_0__Name" name="model.Data[0].Name" type="hidden" value="MyListItem1" /> 
    <input id="model_Data_0__Value" name="model.Data[0].Value" type="text" value="SomeValue" />   
</div> 

mới tạo mark-up là:

<div class="editor-field"> 
    <input id="Data_0__Id" data-val="true" name="Data[0].Id" type="hidden" value="1" data-val-number="The field Id must be a number." data-val-required="The Id field is required." /> 
    <input id="Data_0__ParentId" name="Data[0].ParentId" type="hidden" value="1" data-val="true" data-val-number="The field ParentId must be a number." data-val-required="The ParentId field is required." /> 
    <input id="Data_0__Name" name="Data[0].Name" type="hidden" value="MyListItem1" /> 
    <input id="Data_0__Value" name="Data[0].Value" type="text" value="SomeValue" />   
</div> 

Những kết quả trong các giá trị đăng tải sau:

Id=1&Property1=test1&Property2=test2&Data%5B0%5D.Id=1&Data%5B0%5D.ParentId=1&Data%5B0%5D.Name=MyListItem1&Data%5B0%5D.Value=SomeValue 

Lưu ý rằng không có 'mô hình'. trong tên và đăng tải các giá trị ...

+0

Không được nâng cao chất lượng lốp hoặc bất cứ thứ gì .. Nhưng làm cách nào để cập nhật Danh sách công khai hiện có Dữ liệu {get; bộ; } - thêm một mục, trừ, vv sau đó cập nhật mô hình gốc trên máy khách mà không làm mới màn hình? Làm thế nào về nếu dữ liệu là null, và chỉ có thể được biết đến tại thời gian chạy dựa trên lựa chọn của người dùng các thuộc tính khác của mô hình Phụ huynh? Vâng, tôi đoán nó là một chút của một jack cao hy vọng chúng tôi đang đi theo cùng một hướng:) – user748954

Trả lời

33

Cố gắng thay đổi mã cho bộ sưu tập dữ liệu này, và để cho MVC chăm sóc việc đặt tên:

<div class="editor-field"> 
@for (int i = 0; i < Model.Data.Count(); i++) 
{ 
    @Html.HiddenFor(m => m.Data[i].Id) 
    @Html.HiddenFor(m => m.Data[i].ParentId) 
    @Html.HiddenFor(m => m.Data[i].Name) 
    @Html.TextBoxFor(m => m.Data[i].Value) 
} 
</div> 
+2

Tôi thành thật không thể tin rằng tôi đã bỏ lỡ điều đó. Cảm ơn đã giúp đỡ! – robmzd

+1

Không sao cả! Vui mừng nó đã làm việc ra. – MartinHN

11

Hoặc bạn có thể đã tạo ra một EditorTemplate cho bạn ViewModel lồng nhau như sau.

@model MyDataItem 
@Html.HiddenFor(model => model.Id) 
@Html.HiddenFor(model => model.ParentId) 
@Html.HiddenFor(model => model.Name) 
@Html.TextBoxFor(model => model.Value) 

Tạo thư mục có tên 'EditorTemplates' trong thư mục 'Chia sẻ' và lưu ở trên là 'MyDataItem.cshtml'.

Sau đó, trong View của bạn, chỉ cần gọi sau thay vì foreach loop:

@Html.EditorFor(model => model.Data) 

Cảm thấy một chút ít hackier IMO :)

4

Chỉ cần tôi 2 cent nhưng một cái gì đó đáng chú ý với vấn đề này - thành viên dữ liệu trong Mô hình xem phải được định nghĩa là thuộc tính công khai cho mô hình postback ràng buộc để hoạt động. Tôi đã có một vấn đề rất giống với ở trên nhưng đã sử dụng một thành viên dữ liệu công khai trong Mô hình Xem của tôi. Cùng một HTML được tạo ra như được hiển thị ở trên và tất cả có vẻ tốt nhưng các mô hình chất kết dính đã ném trở lại một bộ sưu tập sản phẩm nào. Đáng xem cho ...

Các vấn đề liên quan