c#-从View中的ViewModel迭代ICollection

我有两个自动生成的数据库模型(Product和ProductDetails),它们已合并到ViewModel中,因此可以一次编辑所有数据.

令我感到困惑的是我应该在视图内迭代Product_ProductCategoryAttributes(在ProductDetail模型内)的ICollection以便允许.NET自动将属性绑定到ViewModel的部分.我尝试过使用for和foreach循环,但都没有成功,因为控件使用错误的名称(需要自动绑定)创建.

产品型号

public partial class Product
{
    public Product()
    {
        this.ProductDetail = new HashSet<ProductDetail>();
    }

    public int idProduct { get; set; }
    public int idProductCategory { get; set; }
    public string EAN { get; set; }
    public string UID { get; set; }
    public bool Active { get; set; }

    public virtual ProductCategory ProductCategory { get; set; }
    public virtual ICollection<ProductDetail> ProductDetail { get; set; }
}

产品详细信息模型

public partial class ProductDetail
{
    public ProductDetail()
    {
        this.Product_ProductCategoryAttribute = new HashSet<Product_ProductCategoryAttribute>();
    }

    public int idProductDetail { get; set; }
    public int idProductCategory { get; set; }
    public int idMeta { get; set; }
    public int idProduct { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }

    public virtual Meta Meta { get; set; }
    public virtual Product Product { get; set; }
    public virtual ICollection<Product_ProductCategoryAttribute> Product_ProductCategoryAttribute { get; set; }
    public virtual ProductCategory ProductCategory { get; set; }
}

ProductViewModel-一个产品可以有多个ProductDetails

public class ProductViewModel
{
    public Product Product { get; set; }
    public List<ProductDetail> ProductDetails { get; set; }

}

视图(有意省略一些代码)

@for (int i = 0; i < Model.ProductDetails.Count(); i++)
{
    @Html.TextAreaFor(model => model.ProductDetails[i].Description, new { @class = "form-control", @rows = "3" })

    @for (int j = 0; j < Model.ProductDetails[i].Product_ProductCategoryAttribute.Count(); j++)
    {
       @Html.HiddenFor(model => model.ProductDetails[i].Product_ProductCategoryAttribute.ElementAt(j).idProductCategoryAttribute)
       @Html.TextBoxFor(model => model.ProductDetails[i].Product_ProductCategoryAttribute.ElementAt(j).Value, new { @class = "form-control" })
    }
 }

第二个for循环之外的所有控件均已正确命名,例如. ProductDetails [0] .Description,但是在第二个for循环中生成的控件通过属性值(在这种情况下为Value和idProductCategoryAttribute)获得名称.如果我没有记错的话,一种解决方案是将ICollection转换为IList,但是自动生成模型不会是最好的选择.

解决方法:

您不能在HTML帮助器的lambda中使用ElementAt().将生成的名称将只是不带索引的字段的名称,这将允许填充发布的值.

您应该使用索引来遍历整个视图模型,以便实际生成的名称匹配.

所以这:

 @Html.HiddenFor(model => model.ProductDetails[i].Product_ProductCategoryAttribute.ElementAt(j).idProductCategoryAttribute)

应该是这样,或类似的:

@Html.HiddenFor(model => model.ProductDetails[i].Product_ProductCategoryAttribute[j].idProductCategoryAttribute)

至于将模型从ICollection更改为IList,这是很好的,因为IList继承自ICollection.但是正如您所说的那样,它是自动生成的,如果您使用的是代码优先实体框架或类似的框架,那可能没问题.

真正的解决方案是将您的传入模型(视图模型)映射到自动生成的ICollection <列出并再次返回,具体取决于您要发布还是获取. 在下面的示例中,我们将获取发布的值,并将其映射到自动生成的Product对象并对其进行操作.

    ///
    /// ProductViewModel incoming model contains IList<> fields, and could be used as the view model for your page
    ///
    [HttpPost]
    public ActionResult Index(ProductViewModel requestModel)
    {
        // Create instance of the auto generated model (with ICollections)
        var product = new Product();

        // Map your incoming model to your auto generated model
        foreach (var productDetailViewModel in requestModel)
        {
             product.ProductDetail.Add(new ProductDetail()
             {
                 Product_ProductCategoryAttribute = productDetailViewModel.Product_ProductCategoryAttribute;

                 // Map other fields here
             }
        }

        // Do something with your product
        this.MyService.SaveProducts(product);

        // Posted values will be retained and passed to view
        // Or map the values back to your valid view model with `List<>` fields
        // Or pass back the requestModel back to the view
        return View();
    }

ProductViewModel.cs

public class ProductViewModel
{
    // This shouldn't be here, only fields that you need from Product should be here and mapped within your controller action
    //public Product Product { get; set; }

    // This should be a view model, used for the view only and not used as a database model too!
    public List<ProductDetailViewModel> ProductDetails { get; set; }
}
上一篇:Javascript-是否有可能淘汰赛更新’initialdata’对象?


下一篇:c#-视图模型放置在N层ASP .NET MVC应用程序中