2009-09-22 8 views
1

커스텀 모델 바인더를 사용하여 액션에서 Order/OrderItem을 바인딩합니다. 이 모델 바인더는 ServiceLocator.Current.GetInstance()를 사용합니다. ICart는 IOrderRepository에 의존합니다 (이것이 중요한지 확실하지 않음).NHibernate + ASP.NET MVC : 모델 바인더의 세션이 닫힙니다.

이제 첫 주문 항목을 만들면 모든 것이 잘 작동합니다. 그리고 두 번째를 만들 때. 그런 다음 두 개의 주문 항목이 포함 된 주문을 표시하려고합니다. 이것은

public ActionResult Show(Order order) {} 

을 사용하여 주문이 내 맞춤 바인더에 바인딩되어 있습니다. 나는에 호출 후, 그 그것의 BindModel를 추적하고 볼

order = cart.GetOrder(id); 

주문 항목은 OK입니다 - 나는 창보기 속성, 제품을 볼 수있는를 추가하고, 그들은 모두 OK 것, 즉. 제어 흐름이 쇼 (주문 순서) 액션 메소드에 올 때

그러나, 순서의 첫 번째 항목은 유효하지 않은 제품이 - (고명 한) 오류를 다음에 그들에게 결과를 액세스 :

NHibernate.LazyInitializationException : 초기화 [Orders.Core.OrderItem # 5440c233-fb7e-4dc9-8aec-9c8c0115808b] 느리게 역할 모음 초기화하기가 실패했습니다 : Orders.Core.OrderItem.Products를 더 세션 또는 세션

폐쇄되지 않은 I 이제 볼 수있는 본 시계 창에서 주문을 볼 때 .Items [0]. 제품.

이상한 것은 두 번째 주문 항목이 여전히 OK입니다! 그래서

  • HTTP 요청과 같이가는 경우 ... 내 모델 바인더 -
  • MVC는 마법
  • 을한다 ... 세션이 모두 주문 항목에 대한 확인이다 - 순서 orderRepository.Get (ID)를 사용하여 얻을 액션 메소드 쇼 (주문 순서) < - 내가보기에 다음 순서에 다른 항목을 추가하는 경우 항목에 대해 [1]하지

동안 여기 order.Items에 대한 세션 [0] .Products는 손실(), 항목 [2]. 제품 만 정확합니다. 항목 [0]과 항목 [1] 제품 모두가 잘못되었습니다 (세션 없음).

여기 무슨 일 이니?

요청 당 샤프 아키텍처 및 세션을 사용합니다. 나는 실제로 모델 바인더와 그 순서를 얻는 사이에 EndRequest가 호출되지 않는다는 것을 확인했다.

UPDATE : 일부 코드 (중요한 라인)

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 아키텍처 저장소입니다 만 EndRequest 이벤트 핸들러에서 세션을 닫습니다 WebSessionStorage 클래스를 사용합니다. 내가 말했듯이 그것은 주문 사이에 불려지지 않는다는 것을 확인했습니다. 주문은 괜찮습니다.

업데이트 : orderRepository.Save (주문) 주변에 추가 수동 트랜잭션이있을 수 있는지 궁금합니다. 내일 조사 할 것이지만, 여기에 비슷한 것을 발견했습니다.

업데이트 : 또한,이는이 이후에 발생합니다

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

내가 다음 주소 표시 줄과 언론에 갈 때 페이지를 다시로드하려면 "입력"은 올바르게 작동합니다. 일회성 문제입니다.

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

그래서 MvcContrib, 내가 말할 것 TempData에 주문을 처리하려고 뭔가가의를 내가 발견

... : 내가 할 경우

재미 게다가, 이러한 버그가 없다 도

[PassParametersDuringRedirect] 
    public class OrdersController 

을 모델 바인더가 불을했다하지만 ... 내 주문 매개 변수가 TempData 대신 ModelBinder를에서 온다 생각 : 컨트롤러에서이 있습니다. 그러나 속성을 제거하면 문제가 사라지지 않습니다. 그래서 그것은 RedirectToController <> MvcContrib에서 나온 것입니다. 그러나 왜 이런 일이 일어나는지 전혀 모릅니다.

답변

0

오 세상에, 나는 [PassParametersDuringRedirect]를 내 BaseController에 넣었습니다. 나는 MvcContrib을 실험 해보고 그것을 잊어 버렸습니다. 그리고 그것은 돌아 왔고 나에게 너무 심하게 물었습니다. 나는 이것을 해결하려고 몇 시간을 잃었습니다.

그래서 문제는 제가 어리 석고, 교훈으로는 시스템 전체의 속성/동작을 절대로해서는 안된다는 것입니다. 부작용에있어 전역 변수보다 낫지 않기 때문입니다.

0

NHibernate.LazyInitializationException : 초기화 [Orders.Core.OrderItem # 5440c233-fb7e-4dc9-8aec-9c8c0115808b] 느리게 역할 수집하는 초기화가 실패했습니다 : Orders.Core.OrderItem.Products없이 세션 또는 세션 폐쇄 됨

은 제품을 요청하기 전에 세션이 폐쇄되었음을 의미합니다. 세션을 닫을 수는 없습니까? 어쩌면 몇 가지 코드를 게시 할 수 있습니까?

+0

일부 코드를 게시했습니다. 그것은 매우 간단합니다. 특별한 것은 없습니다. 제가 지적했듯이, S # arp는 요청이 끝날 때 세션을 닫을 뿐이므로 직접하지 않습니다. 폐쇄되어서는 안됩니다. 그리고 더 이상한 것이 있습니다. 닫힌다면, 왜 마지막 항목이 여전히 OK입니까? – queen3