【问题标题】:ViewModel IEnum<> property is returning null (not binding) when contained in a partial view?ViewModel IEnum<> 属性在包含在部分视图中时返回 null(未绑定)?
【发布时间】:2012-03-29 13:59:04
【问题描述】:

我有一个包含 Product 类型和 IEnumerable 类型的 ViewModel。我有一个在页面顶部显示 ViewModel.Product 的主视图,然后我有一个呈现 ViewModel.IEnumerable 数据的局部视图。在帖子中,第一级产品对象从 ViweModel 返回绑定,而 ViewModel.IEnumerable 返回 null。

当然,如果我删除部分视图并将 IEnumerable 视图移动到主视图,则内容会很好地返回绑定。但是,我需要将这些 Enumerable 项放在部分视图中,因为我计划使用 Ajax 动态更新内容。

为什么 IEnumerable 属性在放置在局部视图中时未绑定?谢谢!

型号:

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; }
}

观看次数:

主索引.cshtml:

@model ViewModelBinding.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>

@Html.Partial("_Product", Model.Products)

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

全景视图_Product.cshtml:

@model List<ViewModelBinding.Models.Product>

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

控制器:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        BoringStoreContext db = new BoringStoreContext();
        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();
    }

}

【问题讨论】:

  • 我从字面上复制并粘贴了您的代码,它对我有用;我看不出有什么不对。可能想调试更多或开始一个新项目,只用你上面的代码来验证。
  • @KurtSchindler:嗨。不,再次查看帖子中的 viewModel.Prodcuts。它是空的。 viewModel.NewProduct 恢复正常。这是用于检查 viewModel.Products 的即时窗口的输出:viewModel.?viewModel.Products.Count。 viewModel.Prodcucts 处于局部视图中,这就是问题的基础......为什么它会返回为空。 'viewModel.Products' 为空

标签: asp.net-mvc asp.net-mvc-3 asp.net-mvc-4


【解决方案1】:

当您使用@Html.Partial("_Product", Model.Products) 时,您的输入字段没有正确的名称。例如,而不是:

<input type="text" name="Products[0].ID" />

你得到:

<input type="text" name="[0].ID" />

只需查看您生成的标记,您就会发现问题所在。这是因为当您使用Html.Partial 时,不会保留导航上下文。输入字段名称没有以集合名称为前缀 - Products,因此模型绑定器无法正确绑定它。查看following blog post 以更好地了解预期的电汇格式。

我建议您使用保留上下文的编辑器模板。所以而不是:

@Html.Partial("_Product", Model.Products)

使用:

@Html.EditorFor(x => x.Products)

现在将您的_Product.cshtml 模板移动到~/Views/Shared/EditorTemplates/Product.cshtml。此外,由于编辑器模板会自动识别 Products 属性是 IEnumerable&lt;T&gt;,因此它将为该集合的每个项目呈现模板。所以你的模板应该被强类型化为单个产品,你可以摆脱循环:

@model Product
<div>
    @Html.LabelFor(model => model.ID)
    @Html.EditorFor(model => model.ID)
</div>
<div>
    @Html.LabelFor(model => model.Name)
    @Html.EditorFor(model => model.Name)
</div>
<div>
    @Html.LabelFor(model => model.Price)
    @Html.EditorFor(model => model.Price)
</div>

现在一切都按约定进行,并且可以正确绑定。

【讨论】:

  • 我确实有一个问题是,部分视图的目的是允许 ajax 更新,以便可以将新产品动态添加到该部分视图中。我还没有测试,但不确定我是否可以使用 EditorFor(而不是部分视图)来完成此操作?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-12
相关资源
最近更新 更多