我正在尝试使用内置模型绑定的MVC 2来处理Web表单中的http-post。从过去几个小时我一直在搜索的内容来看,我认为“物体内的物体”有点挑剔。
我正在寻找任何类型的答案或资源链接,可以帮助我解决这个问题。我还处于这个阶段的早期阶段,所以如果有更好的方法 - 我全都耳朵。我自己编写了Linq-SQL而没有使用代码生成。我认为我最接近的答案是here,但我仍然没有得到它。
模型客户端(我对问题所在的最佳猜测):
public class Client
{
public int ClientID { get; set; }
...
[Column(Name = "Address_id")]
internal int AddressID { get; set; }
internal EntityRef<Address> _address;
[System.Data.Linq.Mapping.Association(ThisKey = "AddressID", Storage = "_address")]
public Address Address
{
get { return _address.Entity; }
internal set { _address.Entity = value; AddressID = value.AddressID; }
}
}
模型地址(在客户实体内)
public class Address
{
[Column] public string Address1 { get; set; }
[Column] public string Address2 { get; set; }
[Column] public string City { get; set; }
...
查看型号:
public class ClientFormViewModel
{
public Client Client { get; set; }
...
}
查看:
<!-- id is hidden -->
<%: Html.EditorFor(m => m.Client.ClientID) %>
...
<%: Html.EditorFor(m => m.Client.Address.AddressID) %>
<%: Html.LabelFor(m => m.Client.Address.Address1) %>
<%: Html.EditorFor(m => m.Client.Address.Address1) %><br />
<%: Html.LabelFor(m => m.Client.Address.Address2) %>
<%: Html.EditorFor(m => m.Client.Address.Address2) %><br />
...
控制器:
public ViewResult Edit(int clientId)
{
var client = clientsRepository.Clients.First(x => x.ClientID == clientId);
...
// create view model
var viewModel = new ClientFormViewModel
{
Client = client,
...
};
return View(viewModel);
}
[HttpPost]
public ActionResult Edit(ClientFormViewModel clientForm)
{
if (ModelState.IsValid)
{
clientsRepository.SaveClient(clientForm.Client);
return RedirectToAction("List");
}
else // validation error, so redisplay the same view
...
}
所以我的问题是......当我进入HttpPost操作时, clientForm.Client.Address 总是 null 。虽然,当我查看 ModelState (有效)或使用 Request。[“key”] 时,所有键都与我对象的结构相匹配。例如,我看到 ModelState [“Client.Address.Address1”] ,“Client.Address.Address2”等。
所有其他基本属性都填写正常,这让我觉得linq-sql代码打破了模型绑定。但是怎么样?有没有办法解决它?如果这些键在Request / ModelState字典中,为什么它们没有映射到对象?我完全错过了一些明显的东西吗?
答案 0 :(得分:0)
如果您希望模型绑定器能够成功绑定它,则Address
setter必须为public
:
internal EntityRef<Address> _address;
[System.Data.Linq.Mapping.Association(ThisKey = "AddressID", Storage = "_address")]
public Address Address
{
get { return _address.Entity; }
set { _address.Entity = value; AddressID = value.AddressID; }
}
我个人建议您使用视图模型,而不是将这些模型传递给视图。
答案 1 :(得分:0)
在@Darin Dimitrov提到使用视图模型而不是传递域模型(我认为我已经在做)之后,我最终找到了解决方案。
我没有依赖默认的模型绑定来获取我的Linq-SQL映射,而是创建了一个展平的视图模型。
这两个帖子对我的帮助最大:
http://geekswithblogs.net/michelotti/archive/2009/10/25/asp.net-mvc-view-model-patterns.aspx
http://lostechies.com/jimmybogard/2009/06/30/how-we-do-mvc-view-models/
我首先遇到了AutoMapper的一些问题,但现在它的效果非常好。我会推荐它!