【问题标题】:MVC View Viewmodel HttpPost returns NULLMVC View Viewmodel HttpPost 返回 NULL
【发布时间】:2020-06-18 04:41:00
【问题描述】:

由于某种原因,我传递的 ViewModel 在 HttpPost 的控制器中返回 NULL,但我不知道为什么。我以为我用@Html.HiddenFor(modelItem => product.Id) 在视图中限定了模型。

我的看法:

@model MaterialOrderFinal.Models.ProductViewmodel

@{
    ViewBag.Title = "Index";
}

@using (Html.BeginForm("Result", "Product", FormMethod.Post))
{
    foreach (var category in Model.ProductCategories)
    {
        <div class="panel panel-default">
            <div class="panel-heading">
                <h4 class="panel-title">
                    <a data-toggle="collapse" href="@($"#collapse{category.Id}")">
                        @Html.DisplayFor(modelItem => category.Name)
                    </a>
                </h4>
            </div>
            <div id="@($"collapse{category.Id}")" class="panel-collapse collapse">
                <div class="panel-body">

                    @foreach (var product in Model.Products.Where(product => product.ProductCategoryId == category.Id))
                    {
                        <div class="col-sm-6">
                            <div class="col-xs-6">
                                @Html.DisplayFor(modelItem => product.Name) <br />
                                @Html.DisplayFor(modelItem => product.Description)
                                @Html.HiddenFor(modelItem => product.Id)
                                @Html.HiddenFor(modelItem => product.Name)
                            </div>
                            <div class="col-xs-6">
                                @Html.RadioButtonFor(modelItem => product.Quantity, 0, new { Name = product.Id, id = product.Id }) <span>0</span> <br />
                                @Html.RadioButtonFor(modelItem => product.Quantity, 50, new { Name = product.Id, id = product.Id }) <span>50</span> <br />
                                @Html.RadioButtonFor(modelItem => product.Quantity, 100, new { Name = product.Id, id = product.Id }) <span>100</span> <br />
                                @Html.RadioButtonFor(modelItem => product.Quantity, 200, new { Name = product.Id, id = product.Id }) <span>200</span>
                            </div>
                        </div>
                    }
                </div>
            </div>
        </div>
    }
    <input type="submit" class="btn btn-default" />
}

我的控制器:

public class ProductController : Controller
{
    private MaterialOrderContext db = new MaterialOrderContext();

    // GET: Product
    public ActionResult Index()
    {
        var products = db.Products.Include(p => p.ProductCategory).ToList();
        var productCategories = db.ProductCategories.ToList();
        var viewModel = new ProductViewmodel { Products = products, ProductCategories = productCategories };
        return View(viewModel);
    }

    [HttpPost]
    public ActionResult Result(ProductViewmodel viewModel)
    {
        var products = viewModel.Products;
        Debug.WriteLine(products.ToString()); // Returns NULL here!
        return View(products);
    }
}

我的视图模型:

public class ProductViewmodel
{
    public IEnumerable<Product> Products { get; set; }
    public IEnumerable<ProductCategory> ProductCategories { get; set; }
}

显示包含我的类别和产品的初始网站,但是一旦我单击提交按钮,我就会收到 NullReferenceError。

【问题讨论】:

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


    【解决方案1】:

    您需要手动创建输入字段并相应地设置name 属性:

    <input name="Products[0].Name" />
    <input name="Products[0].Id" />
    
    <input name="Products[1].Name" />
    <input name="Products[1].Id" />
    

    试试这个代码:

    @using (Html.BeginForm("Result", "Product", FormMethod.Post))
    {
        int index = 0;
    
        foreach (var category in Model.ProductCategories)
        {
            <div class="panel panel-default">
                <div class="panel-heading">
                    <h4 class="panel-title">
                        <a data-toggle="collapse" href="@($"#collapse{category.Id}")">
                            @Html.DisplayFor(modelItem => category.Name)
                        </a>
                    </h4>
                </div>
                <div id="@($"collapse{category.Id}")" class="panel-collapse collapse">
                    <div class="panel-body">
                        @foreach (var product in Model.Products.Where(product => product.ProductCategoryId == category.Id))
                        {
                            <input type="hidden" name="Proucts[@index].Id" value="@product.Id" />
                            <input type="hidden" name="Proucts[@index].Name" value="@product.Name" />
    
                            <div class="col-sm-6">
                                <div class="col-xs-6">
                                    @Html.DisplayFor(modelItem => product.Name) <br />
                                    @Html.DisplayFor(modelItem => product.Description)
                                </div>
                                <div class="col-xs-6">
                                    <input type="radio" name="Products[@index].Quantity" value="0" /> <span>0</span> <br />
                                    <input type="radio" name="Products[@index].Quantity" value="50" /> <span>50</span> <br />
                                    <input type="radio" name="Products[@index].Quantity" value="100" /> <span>100</span> <br />
                                    <input type="radio" name="Products[@index].Quantity" value="200" /> <span>200</span>
                                </div>
                            </div>
    
                            index++;
                        }
                    </div>
                </div>
            </div>
        }
        <input type="submit" class="btn btn-default" />
    }
    

    【讨论】:

    • 谢谢!解决了错误,所选产品显示在结果页面上。现在的问题是不同类别的单选按钮似乎相互分组,如果我为不同类别的产品选择一个按钮,另一个按钮就会消失。 imgur.com/a/akV2hpD 有什么想法吗?
    • @snowcat 很可能是 [0] 索引的重复项。我更新了代码(我将index = 0 移出)。请立即查看
    • 很高兴我能帮上忙 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-10-21
    • 1970-01-01
    • 2015-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多