2012-03-28 21 views
11

Tôi có mô hình chế độ xem có chứa loại Loại sản phẩm và loại Sản phẩm> Loại sản phẩm IEnumerable <. Trên bài đăng, đối tượng sản phẩm cấp đầu tiên được trả về ràng buộc từ viewmodel trong khi enum sản phẩm đang trở về null.Xem mô hình IEnumerable <> tài sản là trở lại null (không ràng buộc) từ phương pháp bài?

Tại sao thuộc tính IEnumerable < Prouduct> không bị ràng buộc vào mô hình xem của tôi trên mỗi bài đăng? Cám ơn!

Models:

public class Product 
{ 
    public int ID { get; set; } 
    public string Name { get; set; } 
    public decimal Price { get; set; } 
} 

public class ProductIndexViewModel 
{ 
    public Product NewProduct { get; set; } 
    public IEnumerable<Product> Products { get; set; } 
} 

public class BoringStoreContext 
{ 
     public BoringStoreContext() 
     { 
      Products = new List<Product>(); 
      Products.Add(new Product() { ID = 1, Name = "Sure", Price = (decimal)(1.10) }); 
      Products.Add(new Product() { ID = 2, Name = "Sure2", Price = (decimal)(2.10) }); 
     } 
     public List<Product> Products {get; set;} 
} 

Xem:

@model ProductIndexViewModel 

@using (@Html.BeginForm()) 
{ 
    <div> 
     @Html.LabelFor(model => model.NewProduct.Name) 
     @Html.EditorFor(model => model.NewProduct.Name) 
    </div> 
    <div> 
     @Html.LabelFor(model => model.NewProduct.Price) 
     @Html.EditorFor(model => model.NewProduct.Price) 
    </div> 
    <div> 
     <input type="submit" value="Add Product" /> 
    </div> 

     foreach (var item in Model.Products) 
     { 
     <div> 
     @Html.LabelFor(model => item.ID) 
     @Html.EditorFor(model => item.ID) 
    </div> 
    <div> 
     @Html.LabelFor(model => item.Name) 
     @Html.EditorFor(model => item.Name) 
    </div> 
    <div> 
     @Html.LabelFor(model => item.Price) 
     @Html.EditorFor(model => item.Price) 
    </div> 

     } 
     } 

Bộ điều khiển:

public class HomeController : Controller 
{ 
    BoringStoreContext db = new BoringStoreContext(); 

    public ActionResult Index() 
    { 
     ProductIndexViewModel viewModel = new ProductIndexViewModel 
     { 
      NewProduct = new Product(), 
      Products = db.Products 
     }; 
     return View(viewModel); 
    } 

    [HttpPost] 
    public ActionResult Index(ProductIndexViewModel viewModel) 
    { 
     // ???? viewModel.Products is NULL here 
     // ???? viewModel.NewProduct comes back fine 

     return View(); 
    } 
+0

Bạn có tùy chỉnh EditorFor của bạn? – Shyju

+0

@Shyju: Xin chào, tôi không .. Tôi giả định rằng nếu tôi tạo một EditorTemplate cho Product.cshtml tôi có thể gọi @ HTml.EditorFor (model => model.Products) và nó có thể sẽ hoạt động? – JaJ

+0

Có thể. Tôi đã thêm một câu trả lời với cách tiếp cận đó. – Shyju

Trả lời

14

Bạn đang không sử dụng biểu thức lambda của bạn đúng cách. Bạn cần truy cập danh sách Sản phẩm thông qua mô hình. Hãy thử làm việc đó như thế này:

@count = 0 
foreach (var item in Model.Products) 
    { 
    <div> 
    @Html.LabelFor(model => model.Products[count].ID) 
    @Html.EditorFor(model => model.Products[count].ID) 
</div> 
<div> 
    @Html.LabelFor(model => model.Products[count].Name) 
    @Html.EditorFor(model => model.Products[count].Name) 
</div> 
<div> 
    @Html.LabelFor(model => model.Products[count].Price) 
    @Html.EditorFor(model => model.Products[count].Price) 
</div> 
@count++ 
    } 

Sửa

Bộ điều khiển:

BoringStoreContext db = new BoringStoreContext(); 

    public ActionResult Index() 
    { 
     ProductIndexViewModel viewModel = new ProductIndexViewModel 
     { 
      NewProduct = new Product(), 
      Products = db.Products 
     }; 
     return View(viewModel); 
    } 

    [HttpPost] 
    public ActionResult Index(ProductIndexViewModel viewModel) 
    { 
     // work with view model 

     return View(); 
    } 

Mẫu

public class Product 
{ 
    public int ID { get; set; } 
    public string Name { get; set; } 
    public decimal Price { get; set; } 
} 

public class ProductIndexViewModel 
{ 
    public Product NewProduct { get; set; } 
    public List<Product> Products { get; set; } 
} 

public class BoringStoreContext 
{ 
    public BoringStoreContext() 
    { 
     Products = new List<Product>(); 
     Products.Add(new Product() { ID = 1, Name = "Sure", Price = (decimal)(1.10) }); 
     Products.Add(new Product() { ID = 2, Name = "Sure2", Price = (decimal)(2.10) }); 
    } 
    public List<Product> Products { get; set; } 
} 

Xem:

@model Models.ProductIndexViewModel 


@using (@Html.BeginForm()) 
{ 
<div> 
    @Html.LabelFor(model => model.NewProduct.Name) 
    @Html.EditorFor(model => model.NewProduct.Name) 
</div> 
<div> 
    @Html.LabelFor(model => model.NewProduct.Price) 
    @Html.EditorFor(model => model.NewProduct.Price) 
</div> 


for (int count = 0; count < Model.Products.Count; count++) 
{ 
    <div> 
    @Html.LabelFor(model => model.Products[count].ID) 
    @Html.EditorFor(model => model.Products[count].ID) 
    </div> 
    <div> 
    @Html.LabelFor(model => model.Products[count].Name) 
    @Html.EditorFor(model => model.Products[count].Name) 
    </div> 
    <div> 
    @Html.LabelFor(model => model.Products[count].Price) 
    @Html.EditorFor(model => model.Products[count].Price) 
    </div> 
} 

<div> 
    <input type="submit" value="Add Product" /> 
</div> 
} 
+1

Tại sao bạn sử dụng vòng lặp foreach để bắt chước vòng lặp thông thường? Và tại sao bạn liên tục gọi model.Products [count] khi bạn đã có mục trong vòng lặp foreach? – rossisdead

+0

@Xander - Cảm ơn bạn. Người trợ giúp không thực sự đáp ứng tốt với việc sử dụng '.' mở rộng để' model.Products.item.ID' không hoạt động do đó việc lập chỉ mục. Tôi đã quên xóa '.item' từ giải pháp và chỉnh sửa nó để phản ánh thay đổi bạn đã nhận xét trong nhận xét đầu tiên của mình. –

+1

@rossisdead - Như đã bình luận ở trên, 'model.Products.item' không hợp lệ ở đây là tốt đẹp như nó sẽ được sử dụng. Một 'for (int count = 0; count

7

Travis's answer sẽ giải quyết vấn đề. Dưới đây là một cách tiếp cận khác bằng cách sử dụng EditorTemplates

Bạn có thể sử dụng Editor template để hiển thị Sản phẩm và sản phẩm sẽ hoạt động tốt.

1) Tạo một thư mục gọi là "EditorTemplates" dưới của bạn thư mục Views/Home

2) Thêm một cái nhìn gọi là "Products" bên trong đó. Thêm mã này vào chế độ xem

@model SO_MVC.Models.Product 
@{ 
    Layout = null; 
} 
<p> 
    @Html.LabelFor(x=>x.ID) 
    @Html.EditorFor(x=>x.ID) 
</p> 
<p> 
    @Html.LabelFor(x=>x.Name) 
    @Html.EditorFor(x=>x.Name) 
</p> 
<p> 
    @Html.LabelFor(x=>x.Price) 
    @Html.EditorFor(x=>x.Price) 
</p> 
@Html.HiddenFor(x=>x.Id) 

và trong Chế độ xem chính, bạn có thể gọi biên tập bản mẫu này như thế này

@Html.EditorFor(m=>m.Products) 
+0

Vâng, điều này hoạt động tốt! ! – JaJ

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