我目前正在开发一个项目,需要为一个客户端添加多个地址。 我有三个型号: 这是我的班级图表的链接:http://sdrv.ms/1fWioA2
人物模型:
public class Person
{
public Person()
{
this.Adresses = new HashSet<Address>();
}
public int PersonID { get; set; }
[Required(ErrorMessage = "Name is required")]
public string Name { get; set; }
[Required(ErrorMessage = "Email Address is required")]
[DisplayName("Email Address")]
//[RegularExpression(@"[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}",
//ErrorMessage = "Email is is not valid.")]
[DataType(DataType.EmailAddress)]
public string Email { get; set; }
public string Mobile { get; set; }
public string Phone { get; set; }
public string Fax { get; set; }
public virtual ICollection<Address> Adresses { get; set; }
}
地址:
public class Address
{
[HiddenInput(DisplayValue = false)]
public int ID { get; set; }
public string Street { get; set; }
public string Building { get; set; }
public int PersonID { get; set; }
public int CityID { get; set; }
public virtual City City { get; set; }
public virtual Person Person { get; set; }
}
我创建了modelview以绑定到我的Create视图:
public class PersonViewModel
{
public Person Person { get; set; }
public ICollection<Address> Adresses { get; set; }
}
我的问题是如何将viewmodel绑定到create视图,以便能够为同一个Person保存多个地址?
答案 0 :(得分:1)
为此,请在/Shared/Editor
中创建一个名为Address.cshtml
的编辑器模板:
@model Address
<div class="address">
@Html.HiddenFor(model => model.ID)
@Html.HiddenFor(model => model.PersonID)
@Html.HiddenFor(model => model.CityID)
@Html.TextBoxFor(model => model.Street) <br />
@Html.TextBoxFor(model => model.Building ) <br />
</div>
现在,在您的View
中,您需要做的就是:
@Html.EditorFor(v => v.Addresses)
这将创建如下的表单字段:
<input type="hidden" name="address[0].Id" />
<input type="hidden" name="address[0].PersonId" />
<input type="hidden" name="address[0].CityId" />
<input type="text" name="address[0].Street" />
<input type="text" name="address[0].Building" />
<input type="hidden" name="address[1].Id" />
<input type="hidden" name="address[1].PersonId" />
<input type="hidden" name="address[1].CityId" />
<input type="text" name="address[1].Street" />
<input type="text" name="address[1].Building" />
模型绑定将看到这些字段符合ASP.Net Wire Format,并将这些字段的值绑定到一组地址中。参考:http://www.hanselman.com/blog/ASPNETWireFormatForModelBindingToArraysListsCollectionsDictionaries.aspx
如果您使用Javascript开始摆弄字段,请小心。如果动态添加或删除地址块,则必须确保将索引重置为从零开始,并且索引始终递增1。
答案 1 :(得分:0)
我建议您使用基于客户端的方法使用knockout作为示例: 服务器端:
public class HomeController : Controller
{
//
// GET: /Home/
public ActionResult Index()
{
var model = new
{
person = new { firstName = "123", secondName = "" },
addresses = new dynamic[1] { new { street = "", building = "", selectedCityId = "" } },
cities = new dynamic[2] { new { cityName = "Kiev", cityId = "1" }, new { cityName = "Moskow", cityId = "2" } }
};
return View(model);
}
public ActionResult Save(YourType model)
{
.....
}
}
客户方:
@{
Layout = null;
}
@using Newtonsoft.Json;
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Index</title>
</head>
<body>
<div style="margin-left:100px">
<p>First name:</p>
<input data-bind="value:person.firstName" />
<p>Second name:</p>
<input data-bind="value:person.secondName" />
<h3>Addresses</h3>
<div data-bind="foreach:addresses">
<p>
Street
</p>
<input data-bind="value:street" />
<p>
Building
</p>
<input data-bind="value:building" />
<p>
City
</p>
<select data-bind="options: $parent.cities, optionsText:
'cityName',optionsValue:'cityId',
value: selectedCityId , optionsCaption: 'Choose...'"></select>
<div>
<div style="float:left;">
<button data-bind="click:$parent.add">
Add
</button>
</div>
<div style="float:left;">
<button data-bind="click: $parent.remove">
Delete
</button>
</div>
</div>
<div style="clear:both"></div>
</div>
<button style="width:100px"data-bind="click:save">
Save
</button>
</div>
<script src="~/Scripts/jquery-1.8.2.js"></script>
<script src="~/Scripts/knockout-3.0.0.js"></script>
<script src="~/Scripts/knockout.mapping-latest.js"></script>
<script type="text/javascript">
//This create javascript object from your model
var personModel=@Html.Raw(JsonConvert.SerializeObject(Model))
//Parse javascript object to knockout viewModel
var viewModel=ko.mapping.fromJS(personModel);
// Create new address
function Address(){
this.selectedCityId=ko.observable("");
this.street=ko.observable("");
this.building=ko.observable("");
}
//Add new address
viewModel.add=function(){
viewModel.addresses.push(new Address());
};
//Remove address
viewModel.remove =function(item){
if(viewModel.addresses().length>1){
viewModel.addresses.remove(item)
}
};
//save model
viewModel.save=function(){
unmapped=ko.mapping.toJSON(viewModel);
$.post('/home/save',unmapped)
};
ko.applyBindings(viewModel);
</script>
</body>
</html>
这里有一些链接http://blog.stevensanderson.com/2010/07/12/editing-a-variable-length-list-knockout-style/也使用这种方法。