是否可以在 MVC 中将一个 ViewModel 放在另一个 ViewModel 中?
Is it possible to have one ViewModel in another ViewModel in MVC?
我有一个供应商可以有多个地址的要求。所以我创建了一个 CommunicationDetailsViewModel
如下所示:
public class CommunicationDetailsViewModel
{
public string OrganizationName { get; set; }
public List<Country> Country { get; set; }
public List<State> State { get; set; }
public List<City> City { get; set; }
[Display(Name = "Id")]
public int CountryId { get; set; }
[Display(Name = "Id")]
public int StateId { get; set; }
[Display(Name = "Id")]
public int CityId { get; set; }
[StringLength(32), Required(ErrorMessage ="Address is required")]
public string Address { get; set; }
}
我还有一个叫 SuppllierInformationViewModel
的 ViewModel
,如下所示:
public class SupplierInformationViewModel
{
[StringLength(50, ErrorMessage = "Organization name cannot be greater than 50 characters"), Required(ErrorMessage ="Organization name is required")]
public string OrganizationName { get; set; }
public List<CommunicationDetailsViewModel> CommunicationDetailsViewModel { get; set; }
}
我创建了这个 ViewModel
因为 Supplier 可以有多个地址。所以创建了一个 CommunicationDetailsViewModel
的集合。更进一步,供应商实体将拥有其他信息,如银行信息、税务信息等。所以我想为每一个创建一个 ViewModel
和一个 SupplierInformationViewModel
来保存所有这些其他 ViewModels
。我们可以创建 ViewModel
个 ViewModels
吗?
在视图中,我必须绑定这多个地址。以下是我的看法:
@model WebAPI.ViewModels.SupplierInformationViewModel
@{
ViewBag.Title = "Supplier Information";
}
<h4>Supplier Details</h4>
@using (Html.BeginForm("Save", "SupplierInformation", FormMethod.Post))
{
<div class="demo-section k-content">
<div class="form-group">
@Html.Label("Organization name")
@Html.Kendo().TextBoxFor(model => model.OrganizationName).Name("OrganizationName").HtmlAttributes(new { @class = "k-textbox required", placeholder = "Organization Name" })
</div>
@for (int i = 0; i < Model.CommunicationDetailsViewModel.Count; i++)
{
<div class="form-group">
@Html.Label("Country")
@(Html.Kendo().DropDownList().Name("CountryId").DataTextField("CountryName").DataValueField("Id").BindTo(Model.CommunicationDetailsViewModel[i].Country))
</div>
<div class="form-group">
@Html.Label("State")
@(Html.Kendo().DropDownList().Name("StateId").DataTextField("StateName").DataValueField("Id").BindTo(Model.CommunicationDetailsViewModel[i].State))
</div>
<div class="form-group">
@Html.Label("City")
@(Html.Kendo().DropDownList().Name("CityId").DataTextField("CityName").DataValueField("Id").BindTo(Model.CommunicationDetailsViewModel[i].City))
</div>
<div class="form-group">
@Html.Label("Address")
@Html.Kendo().TextBoxFor(model => model.CommunicationDetailsViewModel[i].Address).Name("Address").HtmlAttributes(new { @class = "k-textbox required", placeholder = "Address", @maxlength = "32" })
</div>
<div class="form-group">
@Html.Label("Building name")
@Html.Kendo().TextBoxFor(model => Model.CommunicationDetailsViewModel[i].BuildingName).Name("BuildingName").HtmlAttributes(new { @class = "k-textbox required", placeholder = "Address", @maxlength = "32" })
</div>
}
</div>
@Html.Kendo().Button().Name("btnSave").Content("Save").HtmlAttributes(new { type = "submit", @class = "k-button k-primary" })
}
现在,当我 post 返回操作时,我确实在 SupplierInformationViewmodel
中得到 OrganizationName
,但 CommunicationDetailsViewModel
为空。
这是为什么?它与命名约定有什么关系吗?如果是这样,我该如何处理?
任何帮助表示赞赏。
我的操作方法
[HttpPost]
public ActionResult Save(SupplierInformationViewModel supplierInformationViewModel)
{
return View();
}
您需要使用索引和强类型 DropDownListFor()
,以便生成正确的名称属性并指向循环中的项目:
Model.CommunicationDetailsViewModel[i].CountryId
像这样:
@Html.Kendo().DropDownListFor(model => model.CommunicationDetailsViewModel[i].CountryId)
您应该使用强类型 DropDownListFor()
来绑定嵌套视图模型,如下所示:
@(Html.Kendo().DropDownListFor(model => model.CommunicationDetailsViewModel[i].CountryId)
.DataTextField("CountryName")
.DataValueField("Id")
.DataSource(ds => ds.Read(read =>
read.Action("GetCountry", "ControllerName")
))
)
当使用 DropDownListFor()
时,则 Name("CountryId")
变得不必要。
您也可以尝试添加无参数构造函数,它分配 List<CommunicationDetailsViewModel>
的新实例:
public class SupplierInformationViewModel
{
public SupplierInformationViewModel()
{
this.CommunicationDetailsViewModel = new List<CommunicationDetailsViewModel>();
}
[StringLength(50, ErrorMessage = "Organization name cannot be greater than 50 characters"), Required(ErrorMessage ="Organization name is required")]
public string OrganizationName { get; set; }
public List<CommunicationDetailsViewModel> CommunicationDetailsViewModel { get; set; }
}
我有一个供应商可以有多个地址的要求。所以我创建了一个 CommunicationDetailsViewModel
如下所示:
public class CommunicationDetailsViewModel
{
public string OrganizationName { get; set; }
public List<Country> Country { get; set; }
public List<State> State { get; set; }
public List<City> City { get; set; }
[Display(Name = "Id")]
public int CountryId { get; set; }
[Display(Name = "Id")]
public int StateId { get; set; }
[Display(Name = "Id")]
public int CityId { get; set; }
[StringLength(32), Required(ErrorMessage ="Address is required")]
public string Address { get; set; }
}
我还有一个叫 SuppllierInformationViewModel
的 ViewModel
,如下所示:
public class SupplierInformationViewModel
{
[StringLength(50, ErrorMessage = "Organization name cannot be greater than 50 characters"), Required(ErrorMessage ="Organization name is required")]
public string OrganizationName { get; set; }
public List<CommunicationDetailsViewModel> CommunicationDetailsViewModel { get; set; }
}
我创建了这个 ViewModel
因为 Supplier 可以有多个地址。所以创建了一个 CommunicationDetailsViewModel
的集合。更进一步,供应商实体将拥有其他信息,如银行信息、税务信息等。所以我想为每一个创建一个 ViewModel
和一个 SupplierInformationViewModel
来保存所有这些其他 ViewModels
。我们可以创建 ViewModel
个 ViewModels
吗?
在视图中,我必须绑定这多个地址。以下是我的看法:
@model WebAPI.ViewModels.SupplierInformationViewModel
@{
ViewBag.Title = "Supplier Information";
}
<h4>Supplier Details</h4>
@using (Html.BeginForm("Save", "SupplierInformation", FormMethod.Post))
{
<div class="demo-section k-content">
<div class="form-group">
@Html.Label("Organization name")
@Html.Kendo().TextBoxFor(model => model.OrganizationName).Name("OrganizationName").HtmlAttributes(new { @class = "k-textbox required", placeholder = "Organization Name" })
</div>
@for (int i = 0; i < Model.CommunicationDetailsViewModel.Count; i++)
{
<div class="form-group">
@Html.Label("Country")
@(Html.Kendo().DropDownList().Name("CountryId").DataTextField("CountryName").DataValueField("Id").BindTo(Model.CommunicationDetailsViewModel[i].Country))
</div>
<div class="form-group">
@Html.Label("State")
@(Html.Kendo().DropDownList().Name("StateId").DataTextField("StateName").DataValueField("Id").BindTo(Model.CommunicationDetailsViewModel[i].State))
</div>
<div class="form-group">
@Html.Label("City")
@(Html.Kendo().DropDownList().Name("CityId").DataTextField("CityName").DataValueField("Id").BindTo(Model.CommunicationDetailsViewModel[i].City))
</div>
<div class="form-group">
@Html.Label("Address")
@Html.Kendo().TextBoxFor(model => model.CommunicationDetailsViewModel[i].Address).Name("Address").HtmlAttributes(new { @class = "k-textbox required", placeholder = "Address", @maxlength = "32" })
</div>
<div class="form-group">
@Html.Label("Building name")
@Html.Kendo().TextBoxFor(model => Model.CommunicationDetailsViewModel[i].BuildingName).Name("BuildingName").HtmlAttributes(new { @class = "k-textbox required", placeholder = "Address", @maxlength = "32" })
</div>
}
</div>
@Html.Kendo().Button().Name("btnSave").Content("Save").HtmlAttributes(new { type = "submit", @class = "k-button k-primary" })
}
现在,当我 post 返回操作时,我确实在 SupplierInformationViewmodel
中得到 OrganizationName
,但 CommunicationDetailsViewModel
为空。
这是为什么?它与命名约定有什么关系吗?如果是这样,我该如何处理?
任何帮助表示赞赏。
我的操作方法
[HttpPost]
public ActionResult Save(SupplierInformationViewModel supplierInformationViewModel)
{
return View();
}
您需要使用索引和强类型 DropDownListFor()
,以便生成正确的名称属性并指向循环中的项目:
Model.CommunicationDetailsViewModel[i].CountryId
像这样:
@Html.Kendo().DropDownListFor(model => model.CommunicationDetailsViewModel[i].CountryId)
您应该使用强类型 DropDownListFor()
来绑定嵌套视图模型,如下所示:
@(Html.Kendo().DropDownListFor(model => model.CommunicationDetailsViewModel[i].CountryId)
.DataTextField("CountryName")
.DataValueField("Id")
.DataSource(ds => ds.Read(read =>
read.Action("GetCountry", "ControllerName")
))
)
当使用 DropDownListFor()
时,则 Name("CountryId")
变得不必要。
您也可以尝试添加无参数构造函数,它分配 List<CommunicationDetailsViewModel>
的新实例:
public class SupplierInformationViewModel
{
public SupplierInformationViewModel()
{
this.CommunicationDetailsViewModel = new List<CommunicationDetailsViewModel>();
}
[StringLength(50, ErrorMessage = "Organization name cannot be greater than 50 characters"), Required(ErrorMessage ="Organization name is required")]
public string OrganizationName { get; set; }
public List<CommunicationDetailsViewModel> CommunicationDetailsViewModel { get; set; }
}