2009-09-22 6 views
1

J'utilise un classeur de modèle personnalisé pour lier Order/OrderItem dans mes actions. Ce classeur de modèle utilise ServiceLocator.Current.GetInstance(); où ICart dépend à son tour de IOrderRepository (pas sûr si cela compte). Maintenant, tout fonctionne bien lorsque je crée un article de premier ordre. Et quand je crée le second. Ensuite, j'essaie d'afficher la commande qui contient maintenant deux articles de commande. Ceci est fait en utilisantNHibernate + ASP.NET MVC: la session du modèle de classeur est fermée

public ActionResult Show(Order order) {} 

où l'ordre est lié par mon classeur personnalisé. Je trace son bindModel et voir que, après l'appel à

order = cart.GetOrder(id); 

éléments de commande sont OK - à savoir ajouter la à la fenêtre de surveillance, propriétés de la vue, les produits, et ils sont tous OK.

Cependant, lorsque le flux de contrôle est la méthode d'action Show (ordre de commande), premier élément a des produits invalides de l'ordre - les accès aux résultats en erreur suivant (le fameux):

NHibernate.LazyInitializationException: Initialiser [Orders.Core.OrderItem # 5440c233-fb7e-4dc9-8aec-9c8c0115808b] -failed pour initialiser paresseusement une collection de rôle: Orders.Core.OrderItem.Products, aucune session ou session fermée

Je peux maintenant voir cette dans la fenêtre Regarder lors de l'affichage de la commande. Articles [0] .Produits. La chose étrange, c'est que l'article de second ordre est toujours OK! Donc, s'il va comme

  • requête HTTP ... Mon modèle Binder - obtenir l'aide pour orderRepository.Get (id) - session est OK pour les deux éléments de commande ...
  • mvc fait sa magie
  • méthode d'action Afficher (ordre de la commande) < - ici la session pour order.items [0] .Produits est perdu, alors que des articles [1] n'est pas

Si j'ajoute un autre élément à l'ordre, puis au Salon(), seul l'élément [2] .Les produits sont corrects, à la fois l'élément [0] et l'élément [1] Les produits sont défectueux (aucune session).

Que se passe-t-il ici? J'utilise Sharp Architecture et Session par demande. J'ai effectivement vérifié que EndRequest n'est pas appelé entre le classeur modèle obtenant sa commande et Show() en recevant un incorrect.

MISE À JOUR: un code (lignes importantes)

public class Cart : ICart 
{ 
     public Cart(IOrderRepository orderRepository, ICurrentUser currentUser, IUserSessionStorage storage) {} 
     public Order GetOrder(Guid id) 
     { 
     return orderRepository.Get(id); 
     } 
} 

public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { 
    var cart = ServiceLocator.Current.GetInstance<ICart>(); 
    //Guid guidId = new Guid(id_value_from_context); 
    var order = cart.GetOrder(guidId); // here order is OK completely 
    return order; 
} 

OrderRepository est S # arp référentiel d'architecture et utilise la classe WebSessionStorage, qui ne se ferme que session au gestionnaire EndRequest. Comme je l'ai dit, j'ai vérifié qu'il n'est pas appelé entre l'ordre est OK et l'ordre n'est pas.

Mise à jour: Je me demande si cela peut être dû à une transaction manuelle supplémentaire autour de orderRepository.Save (commande). Va enquêter demain, mais a trouvé quelque chose de similaire ici sur SO.

MISE À JOUR: De plus, cela se produit seulement après ceci:

cart.Save(item); 
return RedirectToAction<OrdersController>(c => c.Show(item.Order)); 

Quand je vais ensuite à la barre d'adresse et appuyez sur « Entrée » pour recharger la page, il fonctionne correctement. C'est donc une question ponctuelle.

Ce qui est drôle, il n'y a pas de bug si je fais:

return RedirectToAction("Show", "Orders", new { order = item.Order }); 

Il est donc quelque chose avec MvcContrib essayer de traiter l'ordre dans TempData, je dirais que ...

je trouve que je cette sur les contrôleurs:

[PassParametersDuringRedirect] 
    public class OrdersController 

et pensé que mon paramètre d'ordre vient de TempData au lieu de ModelBinder ... si liant modèle fait feu aussi. Mais quand j'ai enlevé l'attribut, les problèmes n'ont pas disparu. Donc c'est quelque chose avec RedirectToController <> de MvcContrib mais je n'ai aucune idée pourquoi cela se produit.

Répondre

0

Oh mon dieu, j'ai mis [PassParametersDuringRedirect] sur mon BaseController. Je l'ai vraiment fait, à l'époque où j'ai expérimenté avec MvcContrib, et je l'ai juste oublié. Et il est revenu et m'a mordu tellement, j'ai perdu plusieurs heures à essayer de résoudre ça. Donc, le problème est que je suis stupide, et la leçon apprise, c'est qu'on ne devrait jamais faire des attributs/comportements à l'échelle du système, puisque cela n'est pas meilleur que les variables globales au sens des effets secondaires.

0

NHibernate.LazyInitializationException: Initialiser [Orders.Core.OrderItem # 5440c233-fb7e-4dc9-8aec-9c8c0115808b] -failed pour initialiser paresseusement une collection de rôle: Orders.Core.OrderItem.Products, aucune session ou d'une session a été fermé

signifie que vous session fermée avant de demander le produit. êtes-vous sûr que rien ne ferme votre session? peut-être que vous pouvez poster du code?

+0

J'ai posté du code. C'est très simple, cependant. Il n'y a rien de spécial. Comme je l'ai souligné, S # arp ne ferme la session qu'à la fin de la requête, et je ne le fais pas moi-même. Cela ne devrait pas être fermé. Et quoi de plus étrange, si c'est fermé, pourquoi le dernier article en ordre est toujours OK? – queen3