我有以下地址ViewModel:
public class AddressViewModel
{
[StringLength(20, MinimumLength = 2, ErrorMessage = "Country name is too short")]
public String Country { get; set; }
public String City { get; set; }
public String Street { get; set; }
public String Number { get; set; }
public String ApartmentBuilding { get; set; }
public String Sector { get; set; }
}
呈现它的观点:
<div class="control-group offset2 span6">
@Html.LabelFor(m => m.Country)
<div class="controls">
@{
var countryCtrlName = Html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName("Country");
Html.RenderAction("List", "Country", new { ControlName = countryCtrlName });
}
@Html.ValidationMessageFor(m => m.Country)
</div>
</div>
Html.RenderAction(“List”)调用一个控制器方法,该方法从数据库中获取所有国家/地区并使用下拉列表呈现并呈现部分,这是视图:
@model IEnumerable<SelectListItem>
@{var controlName = (string)ViewBag.ControlName;}
@Html.DropDownList(controlName, Model, new {@class = ViewBag.CssClass})
即使我的DropdownList控件使用正确的名称呈现并因此在POST时映射到正确的ViewModel,输入控件也没有使用必要的data-val属性进行修饰以启用客户端验证(我相信这是因为partial的模型是IEnumerable而不是包含国家/地区名称的字符串属性。
地址视图模型通过我的应用程序用作许多视图的嵌套属性。关于如何验证的任何想法?
编辑:根据@ Robert的回答更新了ViewModel:
公共类AddressViewModel { [StringLength(20,MinimumLength = 2,ErrorMessage =“国家名称太短”)] public String Country {get;组; }
public String City { get; set; }
public String Street { get; set; }
public String Number { get; set; }
public String ApartmentBuilding { get; set; }
public String Sector { get; set; }
public IEnumerable<CountryViewModel> CountryList {get; set;}
//Constructor to pass the list of countries
public AddressViewModel(IEnumerable<CountryViewModel> countries)
{
this.CountryList = countries;
}
}
答案 0 :(得分:1)
您是否尝试制作CountryModel并拥有一个单独的控制器来处理您的下拉列表。让控制器返回一个部分视图,您可以将其放在任何您想要的页面上。在CountryModel上有一个具有IEnumerable的属性吗?
地址视图:
@model AddressModel
@Html.Partial("nameOfPartialView", CountryModel)
型号:
public class CountryModel
{
public IEnumerable<Countries> Countries { get; set; }
}
控制器:
public ActionResult Countries()
{
var countries = //get the list from the database
return PartialView(countries);
}
与国家DropDownList的部分视图:
@model CountryModel
@{var controlName = (string)ViewBag.ControlName;}
@Html.DropDownListFor(Model => Model.Countries)
接受国家/地区的控制器:
public ActionResult GetCountry(int CountryId)
{
//do something with the selected country
}
答案 1 :(得分:0)
我认为你的问题是对的:你没有将带注释的模型传递给局部视图,而是传递IEnumerable
SelectListItem
。框架不知道你要显示的是什么:它只知道要调用它。
我可以看到这样做很方便,但它违反了MVC的精神。在这种情况下,您的“模型”实际上不是模型,它只是传递标记项列表(列表项)的一种方式。
我会使用整个AddressViewModel
作为您的模型。这样,您将保留数据注释中的信息,这些信息将告诉您该属性的要求是什么。