使用 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 默认值返回模型以查看错误的主要内容,如果未能解决你的问题,请参考以下文章

如何在Razor视图中选择SelectListItem

csharp 如何在SelectListItem对象列表中返回重复项

脚手架模型/视图:具有键“COLUMN”的 ViewData 项属于“System.String”类型,但必须属于“IEnumerable<SelectListItem>”类型

Django 模型:覆盖字段返回值

mvc DropDownList默认选项

具有键“XXX”的 ViewData 项属于“System.Int32”类型,但必须属于“IEnumerable<SelectListItem>”类型