返回模型以使用selectlistitem默认值查看错误

时间:2021-02-12 17:10:26

i have some issues with default value of my dropdownlist when returning my model to view in case of one or many errors. I have a dropdownlist in the view which is filled from the controller and others empty dropdownlists in the same view which are filled with JSON on selection of the first dropdownlist.

我有一些问题与我的下拉列表的默认值在返回我的模型以查看一个或多个错误时。我在视图中有一个下拉列表,它从控制器和同一视图中的其他空下拉列表中填充,在第一个下拉列表的选择中填充了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);
    }

here, dal is my data access layer and allows me to fill the list of countries from the database. The code use to fill the countries list in the view is like this

这里,dal是我的数据访问层,允许我从数据库中填写国家列表。用于填充视图中的国家/地区列表的代码是这样的

  @Html.DropDownListFor(m => m.selectedcountry, new  SelectList(Model.countries, "Value", "Text", Model.selectedcountry), "-Select a Country-", new { @class = "ddlist" })

one of the empty dropdowlists is as the one below

其中一个空的下拉列表如下所示

 @Html.DropDownListFor(m => m.selectedtown, new SelectList(Enumerable.Empty<SelectListItem>(), "Value", "Text", Model.selectedtown), "-Select a Town/City-", new { @class = "ddlist" })

This code work very well i reach the page for the first time because i have set a default value for country dropdownlist which is select a country. i use the following code to post my form.

这段代码非常有效,我第一次到达页面,因为我已经为国家/地区下拉列表设置了一个默认值,即选择一个国家/地区。我使用以下代码发布我的表单。

    [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");
    }

If the form contains errors, my model is returned back to my view with the posted value of country selected dropdownlist as default, which is not my goal because the others dropdowlists which are filled using JSON on the country dropdownlist selection change are empty.Thus, I ought to select this same country once to fill the others dropdowlists, which is cumbersome. To be logic, i would like to send back my model to my view with default value of the dropdowlist of country when an error occurs. I am using MVC4 and VS 2010

如果表单包含错误,我的模型将返回到我的视图,默认情况下,国家/地区选定下拉列表的已发布值,这不是我的目标,因为在国家/地区下拉列表选择更改中使用JSON填充的其他下拉列表是空的。因此,我应该选择同一个国家一次来填补其他的下拉列表,这很麻烦。为了逻辑,我想在发生错误时将我的模型发送回我的视图,其中包含国家/地区下拉列表的默认值。我正在使用MVC4和VS 2010

1 个解决方案

#1


1  

You need to populate both SelectList's in the controller methods so they get passed to the view. In the GET method, the 2nd one will be an empty SelectList (assuming its a 'Create' metod), but in the POST method it will be populated based on the country that has been selected.

您需要在控制器方法中填充两个SelectList,以便将它们传递给视图。在GET方法中,第二个将是一个空的SelectList(假设它是'Create'metod),但在POST方法中,它将根据已选择的国家进行填充。

You model should include

你的模型应该包括

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; }
}

And your controller methods

和你的控制器方法

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>());
    }
}

This also allows you to generate the correct options and default selections when editing an existing CountrydetailsViewModel.

这还允许您在编辑现有CountrydetailsViewModel时生成正确的选项和默认选择。

Then in the view, use

然后在视图中,使用

@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)

Note that there is no point creating an identical SelectList from the original one you passed to the view by using new SelectList(..) - its just unnecessary extra overhead. Note also that the last parameter in the SelectList constructor is ignored when your binding to a model property (internally the method builds its own SelectList based on the value of the property) - you could put whatever value you wanted as the last parameter and you will see that the option is still correct selected based on the value of the property.

请注意,使用新的SelectList(..)从传递给视图的原始SelectList创建一个相同的SelectList是没有意义的 - 它只是不必要的额外开销。还要注意,当你绑定到一个模型属性时,会忽略SelectList构造函数中的最后一个参数(在方法内部,根据属性的值构建自己的SelectList) - 你可以把你想要的任何值作为最后一个参数,你会看到根据属性的值选择了仍然正确的选项。

#1


1  

You need to populate both SelectList's in the controller methods so they get passed to the view. In the GET method, the 2nd one will be an empty SelectList (assuming its a 'Create' metod), but in the POST method it will be populated based on the country that has been selected.

您需要在控制器方法中填充两个SelectList,以便将它们传递给视图。在GET方法中,第二个将是一个空的SelectList(假设它是'Create'metod),但在POST方法中,它将根据已选择的国家进行填充。

You model should include

你的模型应该包括

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; }
}

And your controller methods

和你的控制器方法

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>());
    }
}

This also allows you to generate the correct options and default selections when editing an existing CountrydetailsViewModel.

这还允许您在编辑现有CountrydetailsViewModel时生成正确的选项和默认选择。

Then in the view, use

然后在视图中,使用

@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)

Note that there is no point creating an identical SelectList from the original one you passed to the view by using new SelectList(..) - its just unnecessary extra overhead. Note also that the last parameter in the SelectList constructor is ignored when your binding to a model property (internally the method builds its own SelectList based on the value of the property) - you could put whatever value you wanted as the last parameter and you will see that the option is still correct selected based on the value of the property.

请注意,使用新的SelectList(..)从传递给视图的原始SelectList创建一个相同的SelectList是没有意义的 - 它只是不必要的额外开销。还要注意,当你绑定到一个模型属性时,会忽略SelectList构造函数中的最后一个参数(在方法内部,根据属性的值构建自己的SelectList) - 你可以把你想要的任何值作为最后一个参数,你会看到根据属性的值选择了仍然正确的选项。