MVC4模型绑定 - 传递自定义视图模型&从视图到控制器的值

时间:2014-03-06 00:37:05

标签: c# asp.net-mvc asp.net-mvc-4

我有一个强类型视图,其中包含以下模型。

public class ProductViewModel
{
    public Product Product { get; set; }
    public List<ProductOptionWithValues> ProductOptionsWithValues { get; set; }
}

public class ProductOptionWithValues
{
    public ProductOption ProductOption;
    public List<AllowedOptionValue> AllowedOptionValues;
}

我正在使用此模型填充表单,用户可以在其中选择产品所需的选项。 这是观点。

@model AsoRock.Entities.ViewModels.ProductViewModel

@{
    ViewBag.Title = "Details";
}
@using (Html.BeginForm(new { ReturnUrl = ViewBag.ReturnUrl })) 
{
    @Html.AntiForgeryToken()
    @Html.ValidationSummary(true)
    <h3> 
        @Html.DisplayFor(model => model.Product.ProductName)

        ----> @Html.DisplayFor(model => model.Product.Price) 
    </h3>
    <br/>

    foreach (var item in Model.ProductOptionsWithValues)
    {
        <b>@Html.DisplayFor(modelItem => item.ProductOption.Option.OptionName)</b>
        <br/>

        @Html.DropDownListFor(m => m.ProductOptionsWithValues, 
                new SelectList(item.AllowedOptionValues, 
                "Id", "DisplayString", 
                item.AllowedOptionValues.First().Id))
        <br/>
    }
    <input type="submit" value="Add to cart" />
}

在我的控制器中,我试图将模型传回去。当我在控制器中设置一个断点时它会命中它,但是产品视图模型是空的,任何想法如何将视图中选择的值返回到我的控制器?

[HttpPost]
public ActionResult Details(ProductViewModel ProductViewModel)
{
    return View();
    //return View();
}

1 个答案:

答案 0 :(得分:0)

如评论中所述,您需要将viewmodel参数的名称从ProductViewModel更改为其他名称,例如

[HttpPost]
public ActionResult Details(ProductViewModel viewModel)
{
}

现在很奇怪viewModel param没有设置为类的实例。 MVC模型绑定器仍然会创建ProductViewModel的实例,即使它的所有属性都没有设置为任何属性。你有没有使用自定义模型绑定器?

此外,我强烈建议您的viewmodel类没有Product属性。而是在viewmodel中专门为您打算使用的Product属性创建属性,例如。

public class ProductViewModel
{
    public string ProductName { get; set; }
    public decimal ProductPrice { get; set; }
    public List<ProductOptionWithValues> ProductOptionsWithValues { get; set; }
}

在viewmodel中使用Product会破坏拥有viewmodel的意义。视图模型应仅包含视图所需的最小值。包括Product意味着视图模型现在膨胀了它不使用/不需要的额外数据。

编辑:

在你的鞋子里,我会使用视图模型的一小部分来剥离视图本身,并向控制器发送POST以查看发生了什么。如果viewmodel calss不为NULL,请返回视图并再添加一个位。继续这样做,直到viewmodel再次为NULL。一点一点地这样做应该会有所帮助。