Model Relationships in ASP.NET MVC

I recently started evaluating ASP.NET MVC. Although it is very simple and quick to create controllers and views for models with only primitive properties (as shown in the start videos from the official page), I did not find a suitable way to work with links to complex types. Let's say I have these Models:

public class Customer { public int Id { get; set; } public string Name { get; set; } public Address Address { get; set; } public IList<Order> 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; } ..... } 

Note that I do not have foreign keys in the models (as is typical for LINQ to SQL, which is also used in the sample video), but an object reference.

How can I handle such links in asp.net mvc? Does anyone have any good tips or links to tutorials on this issue? possibly including auto knit with complex types.

+4
source share
3 answers

I would combine everything into my view model:

 CustomerViewModel.Customer CustomerViewModel.Address CustomerViewModel.Orders // maybe an IEnumerable<Order> CustomerViewMode.CurrentOrder 

You should be able to bind complex objects without any problems with some input helpers:

 //.. 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 .. 

If your action method looks like this:

 [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 } 

Hal

+1
source

You can use data transfer objects for this problem, or you can use the expand methods for the Entity include method in EF -

Nothing is different from primitive properties. If this is not what you mean, correct me, I will help you again.

thanks

DTO:

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

NHibernate Storage:

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

View:

With Expand - Enable - Model Type - "Order":

 <%= Model.Customer.Name %> 

With DTO - model type - "OrderDTO":

 <%= Model.CustomerName %> 

edit:

Ok, first you can use FormViewModel to create / edit actions. eg:

Controller:

 public ActionResult Edit(int id) { Order order = null; // OrderService.Get(id); IList<Customer> 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<SelectListItem> Customers { get; internal set; } public int CustomerId { get; internal set; } } 

View:

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

I prefer my views to look “dumb”, so I like to create custom view models for snapping.

In your controller, you can map the objects of your rich domain to the model model of the view model. For instance:

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

If you are looking for good material on this topic, I recommend ASP.NET MVC View Model Templates .

+1
source

Source: https://habr.com/ru/post/1310954/


All Articles