模型绑定问题
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
的值(有关详细信息,请参阅 )
我创建了一个名为 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
的值(有关详细信息,请参阅