4 votes

Relations entre les modèles dans ASP.NET MVC

J'ai récemment commencé à évaluer ASP.NET MVC. Bien qu'il soit vraiment facile et rapide de créer des contrôleurs et des vues pour des modèles avec seulement des propriétés primitives (comme montré dans les vidéos de démarrage de la page officielle), je n'ai pas trouvé de bonne façon de travailler avec des références à des types complexes. Disons que j'ai ces modèles :

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; }  
    .....  
}

Notez que je n'ai pas de clés étrangères dans les modèles (comme c'est typiquement le cas pour LINQ to SQL, qui est également utilisé dans la vidéo d'exemple) mais une référence d'objet.

Comment puis-je gérer de telles références dans asp.net mvc ? Je ne sais pas si vous avez des conseils ou des liens vers des tutoriels sur ce problème, mais je pense qu'il est possible d'inclure l'autobinding avec des types complexes.

3voto

cem Points 1059

Vous pouvez utiliser des objets de transfert de données pour résoudre ce problème ou utiliser des méthodes d'expansion sur l'entité - méthode d'inclusion dans EF -.

Rien n'est différent avec les propriétés primitives. Si ce n'est pas ce que vous voulez dire, corrigez-moi et je vous aiderai à nouveau.

Remerciements

DTO :

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

Référentiel NHibernate :

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

Vue :

Avec Expand - Include - Le type de modèle est "Order" :

<%= Model.Customer.Name %>

Avec DTO - Le type de modèle est "OrderDTO" :

<%= Model.CustomerName %>

éditer :

Tout d'abord, vous pouvez utiliser FormViewModel pour les actions de création/édition, comme ceci ;

Contrôleur :

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

Vue :

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

1voto

Hal Points 809

Je combinerais le tout dans mon modèle de vue :

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

Vous devriez être en mesure de lier vos objets complexes sans trop de difficultés en utilisant certaines des aides à la saisie :

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

La liaison devrait être correcte si votre méthode d'action ressemble à :

[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

1voto

Jeff Sternal Points 30147

Je préfère garder mes vues aussi "stupides" que possible, et j'aime donc créer des modèles de vue personnalisés pour les lier.

Dans votre contrôleur, vous pouvez faire correspondre vos objets de domaine riche au modèle de vue plus plat. Par exemple, dans le contrôleur, vous pouvez faire correspondre vos objets de domaine riche au modèle plus plat du modèle de vue :

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

Si vous êtes à la recherche d'un bon matériel sur ce sujet, je vous recommande Modèle de vue ASP.NET MVC .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X