模型绑定问题

Issue with Model Binding

我创建了一个名为 CompetitionRoundModel 的视图模型,部分生成如下:

public class CompetitionRoundModel
{
    public IEnumerable<SelectListItem> CategoryValues
    {
        get
        {
            return Enumerable
                .Range(0, Categories.Count())
                .Select(x => new SelectListItem
                {
                    Value = Categories.ElementAt(x).Id.ToString(),
                    Text = Categories.ElementAt(x).Name
                });
        }
    }

    [Display(Name = "Category")]
    public int CategoryId { get; set; }

    public IEnumerable<Category> Categories { get; set; }

    // Other parameters
}

我以这种方式构建了模型,因为我需要根据存储在 CategoryValues 中的值填充下拉列表。所以在我看来,我有:

@using (Html.BeginForm())
{
    <div class="form-group">
        @Html.LabelFor(model => model.CategoryId, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.DropDownListFor(model => model.CategoryId, Model.CategoryValues, new { @class = "form-control" })
            @Html.ValidationMessageFor(model => model.CategoryId, "", new { @class = "text-danger" })
        </div>
    </div>
    // Other code goes here
}

我在 DropDownListFor() 方法中选择了 model.CategoryId,因为我想将所选值绑定到 CategoryId。我真的不关心 CategoryValues,我只需要它来填充 DropDown。

我现在的问题是,当我的控制器在操作方法中接收到我的模型的值时,CategoryValues 为 null,这导致系统抛出 ArgumentNullException(突出显示的行是return Enumerable 行。

我什至试过 [Bind(Exclude="CategoryValues")] 但一点改变也没有。任何帮助将不胜感激。

由于 CategoryValues 只是填充下拉列表,它永远不会 post 返回服务器,您需要在 GET 或 POST 操作。 CategoryId 属性 是将从 DropDownList posted 回服务器的值。

您没有(也不应该)为 IEnumerable<Category> 集合中每个 Category 的每个 属性 创建表单控件,因此在您的 POST 方法中,值Categories 的是 null(它永远不会被初始化)。一旦您尝试 CategoryValues 并且 getter.

中的 .Range(0, Categories.Count()) 代码行抛出异常

更改您的视图模型以给 CategoryValues 一个简单的 geter/setter,并删除 Categories 属性

public class CompetitionRoundModel
{
    public IEnumerable<SelectListItem> CategoryValues { get; set; }
    [Display(Name = "Category")]
    public int CategoryId { get; set; }
    .... // Other properties
}

并在控制器方法中填充 SelectList,例如

var categories db.Categories; // your database call
CompetitionRoundModel model = new CompetitionRoundModel()
{
    CategoryValues = categories.Select(x => new SelectListItem()
    {
        Value = x.Id.ToString(),
        Text = x.Name
    },
    ....
};
return View(model);

或者

CompetitionRoundModel model = new CompetitionRoundModel()
{
    CategoryValues = new SelectList(categories, "Id", "Name" ),

另请注意,如果您 return 视图(因为 ModelState 无效,您需要重新填充 CategoryValues 的值(有关详细信息,请参阅 )