使用 selectlistitem 默认值返回模型以查看错误
Posted
技术标签:
【中文标题】使用 selectlistitem 默认值返回模型以查看错误【英文标题】:return model to view on error with selectlistitem default value 【发布时间】:2017-03-10 18:04:26 【问题描述】:在返回我的模型以查看一个或多个错误时,我的下拉列表的默认值存在一些问题。我在视图中有一个下拉列表,该下拉列表由控制器填充,而同一视图中的其他空下拉列表在选择第一个下拉列表时填充 JSON。
public ActionResult Countriesdata()
CountrydetailsViewModel vm= new CountrydetailsViewModel();
vm.countries= dal.countries().Select(x => new SelectListItem Text = x.Name, Value = x.CountryID.ToString() )
.ToList();
return View(vm);
这里,dal 是我的数据访问层,允许我从数据库中填写国家/地区列表。用于在视图中填充国家列表的代码是这样的
@html.DropDownListFor(m => m.selectedcountry, new SelectList(Model.countries, "Value", "Text", Model.selectedcountry), "-Select a Country-", new @class = "ddlist" )
其中一个空的下拉列表如下所示
@Html.DropDownListFor(m => m.selectedtown, new SelectList(Enumerable.Empty<SelectListItem>(), "Value", "Text", Model.selectedtown), "-Select a Town/City-", new @class = "ddlist" )
此代码运行良好,我第一次到达该页面,因为我为国家下拉列表设置了一个默认值,即选择一个国家。我使用以下代码发布我的表单。
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Countriesdata(CountrydetailsViewModel returnmodel)
if (! ModelState.IsValid)
returnmodel.countries= dal.countries().Select(x => new SelectListItem Text = x.Name, Value = x.CountryID.ToString() )
.ToList();
return View(returnmodel);
return RedirectToAction("mainpage");
如果表单包含错误,我的模型将返回到我的视图,默认显示国家/地区选择下拉列表的发布值,这不是我的目标,因为在国家/地区下拉列表选择更改中使用 JSON 填充的其他下拉列表为空.因此,我应该选择同一个国家一次来填充其他dropdowlists,这很麻烦。从逻辑上讲,我想在发生错误时将我的模型发送回我的视图,并使用国家下拉列表的默认值。我正在使用 MVC4 和 VS 2010
【问题讨论】:
【参考方案1】:您需要在控制器方法中填充两个SelectList
,以便将它们传递给视图。在 GET 方法中,第二个将是一个空的 SelectList
(假设它是一个 'Create' 方法),但在 POST 方法中,它将根据已选择的国家来填充。
你的模型应该包括
public class CountrydetailsViewModel
[Required(Error Message = "..")]
public int? SelectedCountry get; set;
[Required(Error Message = "..")]
public int? SelectedTown get; set;
....
public IEnumerable<SelectListItem> CountryList get; set;
public IEnumerable<SelectListItem> TownList get; set;
还有你的控制器方法
public ActionResult Countriesdata()
CountrydetailsViewModel vm = new CountrydetailsViewModel();
ConfigureViewModel(vm);
return View(vm);
[HttpPost]
public ActionResult Countriesdata(CountrydetailsViewModel returnmodel)
if(!ModelState.IsValid)
ConfigureViewModel(returnmodel);
return View(returnmodel);
.... // save and redirect
private ConfigureViewModel(CountrydetailsViewModel model)
var countries = dal.countries();
model.CountryList= countries.Select(x => new SelectListItem
Text = x.Name,
Value = x.CountryID.ToString()
);
if (model.SelectedCountry.HasValue)
// adjust query to suit your property names
var towns = db.towns.Where(e => e.CountryId == model.SelectedCountry);
model.TownList = towns.Select(x => new SelectListItem
Text = x.Name,
Value = x.TownID.ToString()
);
else
model.TownList = new SelectList(Enumerable.Empty<SelectListItem>());
这还允许您在编辑现有 CountrydetailsViewModel
时生成正确的选项和默认选择。
然后在视图中,使用
@Html.DropDownListFor(m => m.SelectedCountry, Model.CountryList, "-Select a Country-", new @class = "ddlist" )
@Html.ValidationMessageFor(m => m.SelectedCountry)
@Html.DropDownListFor(m => m.SelectedTown, Model.TownList, "-Select a Country-", new @class = "ddlist" )
@Html.ValidationMessageFor(m => m.SelectedTown)
请注意,使用new SelectList(..)
从传递给视图的原始SelectList
创建一个相同的SelectList
是没有意义的——这只是不必要的额外开销。另请注意,当您绑定到模型属性时,SelectList
构造函数中的最后一个参数将被忽略(该方法在内部根据属性的值构建自己的SelectList
) - 您可以将任何您想要的值作为最后一个参数,您将看到根据属性值选择的选项仍然正确。
【讨论】:
+1 for @Stephen Muecke,我已经根据我的需要实现了你的代码,它就像一个魅力。非常感谢 那么也许你应该考虑接受这个答案来解决这个问题(以及对你问题的其他答案,包括你自己解决问题的答案)以上是关于使用 selectlistitem 默认值返回模型以查看错误的主要内容,如果未能解决你的问题,请参考以下文章
csharp 如何在SelectListItem对象列表中返回重复项
脚手架模型/视图:具有键“COLUMN”的 ViewData 项属于“System.String”类型,但必须属于“IEnumerable<SelectListItem>”类型
具有键“XXX”的 ViewData 项属于“System.Int32”类型,但必须属于“IEnumerable<SelectListItem>”类型