ASP.NET MVC中的模型关系

我最近开始评估ASP.NET MVC。 虽然为仅具有原始属性的模型创建控制器和视图非常简单快捷(如官方页面中的入门video中所示),但我没有找到任何使用复杂类型引用的好方法。 比方说,我有这些模型:

public class Customer { public int Id { get; set; } public string Name { get; set; } public Address Address { get; set; } public IList Orders { get; set; } } public class Address { public int Id { get; set; } public string ..... ..... } public class Order { public int Id { get; set; } public Customer Customer { get; set; } public string OrderName { get; set; } ..... } 

请注意,我在模型中没有外键(就像它通常用于LINQ to SQL,它也用在示例video中)而是一个对象引用。

我怎样才能在asp.net mvc中处理这样的引用? 有人有关于此问题的教程的一些好的提示或链接吗? 可能包括复杂类型的自动绑定。

我会将所有内容组合到我的视图模型中:

 CustomerViewModel.Customer CustomerViewModel.Address CustomerViewModel.Orders // maybe an IEnumerable CustomerViewMode.CurrentOrder 

您应该能够使用某些输入帮助程序绑定复杂对象而不会有太多麻烦:

 //.. begin form <%=Html.HiddenFor(m=>m.Customer.Id)%> <%=Html.TextboxFor(m=>m.Customer.FirstName)%> <%=Html.TextBoxFor(m=>m.Address.City)%> <%=Html.TextBoxFor(m=>m.ActiveOrder.OrderName%> //.. submit .. //.. end form .. 

如果您的操作方法如下所示,应该绑定回来:

 [HttpPost] public ActionResult UpdateComplexObject(string id, CustomerViewModel customerViewModel) { // if (!id.Equals(customerViewModel.Customer.Id) throw something // just one of my own conventions to ensure that I am working on the correct active // entity - string id is bound from the route rules. ValidateModel(customerViewModel); service.UpdateCustomer(customerViewModel.Customer); serviceOrder.UpdateOrder(customerViewModel.ActiveOrder); serviceAddress.UpdateAddress(customerViewModel.Address); return RedirectToAction("DisplayComplexObject"); // or whatever } 

哈尔

您可以使用数据传输对象来解决此问题,也可以在实体中使用扩展方法 – 在EF中使用include方法 –

原始属性没有什么不同。 如果这不是你的意思,请纠正我,然后我会再次帮助你

谢谢

DTO:

 public class OrderDTO { public int Id { get; set; } public int CustomerId { get; set; } public string CustomerName { get; set; } } 

NHibernate存储库:

 public IList GetOrders() { return Session.Linq() .Select(o => new OrderDTO { Id = o.Id CustomerId = o.Customer.Id CustomerName = o.Customer.Name ... }).ToList(); } 

视图:

使用Expand – Include – 模型类型为’Order’:

 <%= Model.Customer.Name %> 

使用DTO – 模型类型是’OrderDTO’:

 <%= Model.CustomerName %> 

编辑:

好的,首先您可能希望使用FormViewModel进行创建/编辑操作。 像这样;

控制器:

 public ActionResult Edit(int id) { Order order = null; // OrderService.Get(id); IList customers = null; // CustomerService.GetAll(); OrderFormViewModel model = OrderFormViewModel.Create(order); model.Customers = customers.Select(c => new SelectListItem { Value = c.Id, Text = c.Name }); return View(model); } [HttpPost] public ActionResult Edit(int customerId, Order order) { //customerId - selected from dropdown. } public class OrderFormViewModel { public static OrderFormViewModel Create(Order order) { return new OrderFormViewModel { Order = order }; } public Order Order { get; internal set; } public IEnumerable Customers { get; internal set; } public int CustomerId { get; internal set; } } 

视图:

 <%= Html.DropDownListFor(o => o.CustomerId, Model.Customers) %> 

我更喜欢让我的观点尽可能“愚蠢”,所以我喜欢为绑定创建自定义视图模型。

在控制器中,您可以将富域对象映射到视图模型的更平坦的模型。 例如:

 public class ChooseCustomerModel { public Order Order { get; set; } // Project Customer objects into this container, which is easy to bind to public IDictionary PotentialCustomers { get; set; } } 

如果您正在寻找有关此主题的优秀材料,我建议使用ASP.NET MVC View Model Patterns 。