Я использую привязку пользовательской модели для привязки Order / OrderItem в своих действиях. Эта модель связывания использует ServiceLocator.Current.GetInstance (); где ICart, в свою очередь, зависит от IOrderRepository (не уверен, имеет ли это значение).
Теперь все работает нормально, когда я создаю элемент первого заказа. И когда я создаю второй. Затем я пытаюсь отобразить заказ, который теперь содержит два элемента заказа. Это делается с помощью
public ActionResult Show(Order order) {}
, где порядок связан с моим пользовательским переплетом. Я отслеживаю его BindModel и вижу, что после вызова
order = cart.GetOrder(id);
элементы заказа в порядке - то есть я добавляю окно «Просмотр», просматриваю свойства, продукты, и все они в порядке.
Однако, когда поток управления переходит к методу действия Показать (заказ), первый элемент заказа имеет недопустимые продукты - при доступе к ним возникает следующая ошибка (известная):
NHibernate.LazyInitializationException: инициализация [Orders.Core.OrderItem # 5440c233-fb7e-4dc9-8aec-9c8c0115808b] - не удалось лениво инициализировать коллекцию ролей: Orders.Core.OrderItem.Products, ни один сеанс или сессия не были закрыты
Теперь я вижу это в окне Watch при просмотре заказа. Элементы [0] .Products.
Странно то, что второй пункт заказа все еще в порядке! Так что, если он пойдет как
- HTTP-запрос ... Моя модель Binder - получить заказ с помощью orderRepository.Get (id) - сессия в порядке для обоих элементов заказа ...
- MVC делает свое волшебство
- метод действия Show (Order order) <- здесь сеанс для order.Items [0]. Продукты потеряны, а для Items [1] нет </li>
Если я добавлю еще один элемент к заказу, то в Show () будет отображаться только элемент [2]. Продукты верны, оба элемента [0] и элемент [1] плохие (без сеанса).
Что здесь происходит?
Я использую Sharp Architecture и Session для каждого запроса. Я на самом деле убедился, что EndRequest не вызывается между механизмом связывания модели, получающим свой заказ, и Show (), получающим неправильный.
ОБНОВЛЕНИЕ: некоторый код (важные строки)
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 является репозиторием S # arp Architecture и использует класс WebSessionStorage, который закрывает Session только в обработчике EndRequest. Как я уже сказал, я подтвердил, что НЕ вызывается между заказом в порядке и заказом нет.
Обновление: Интересно, может ли это быть из-за дополнительной ручной транзакции вокруг orderRepository.Save (order). Завтра займусь расследованием, но нашел здесь что-то похожее на SO.
ОБНОВЛЕНИЕ: Более того, это происходит только после этого:
cart.Save(item);
return RedirectToAction<OrdersController>(c => c.Show(item.Order));
Когда я иду в адресную строку и нажимаю «Enter», чтобы перезагрузить страницу, она работает правильно. Так что это разовая проблема.
Что смешно, если я это сделаю, такой ошибки не будет:
return RedirectToAction("Show", "Orders", new { order = item.Order });
Так что MvcContrib пытается обработать порядок в TempData, я бы сказал ...
Я обнаружил, что у меня это на контроллерах:
[PassParametersDuringRedirect]
public class OrdersController
и подумал, что мой параметр заказа прибывает из TempData вместо ModelBinder ... хотя связыватель модели тоже срабатывал. Но когда я удалил атрибут, проблемы не исчезли. Так что это что-то с RedirectToController <> от MvcContrib, но я понятия не имею, почему это происходит.