Asp.net mvc 刷新页面时,NHibernate会话关闭
这是我这几天遇到的另一个奇怪的问题!!!我已经使用nhibernate创建和安装了MVC4应用程序。并在my HomeController上添加了名为[LoggingNHibernateSessionAttribute]的筛选器属性,该属性管理每个操作的会话。我关注了“ASP.NETMVC4和Apress发布的Web API”Asp.net mvc 刷新页面时,NHibernate会话关闭,asp.net-mvc,asp.net-mvc-4,session,nhibernate,Asp.net Mvc,Asp.net Mvc 4,Session,Nhibernate,这是我这几天遇到的另一个奇怪的问题!!!我已经使用nhibernate创建和安装了MVC4应用程序。并在my HomeController上添加了名为[LoggingNHibernateSessionAttribute]的筛选器属性,该属性管理每个操作的会话。我关注了“ASP.NETMVC4和Apress发布的Web API” public class LoggingNHibernateSessionAttribute : ActionFilterAttribute { private
public class LoggingNHibernateSessionAttribute : ActionFilterAttribute
{
private readonly IActionLogHelper _actionLogHelper;
private readonly IActionExceptionHandler _actionExceptionHandler;
private readonly IActionTransactionHelper _actionTransactionHelper;
public LoggingNHibernateSessionAttribute()
: this(WebContainerManager.Get<IActionLogHelper>(),
WebContainerManager.Get<IActionExceptionHandler>(),
WebContainerManager.Get<IActionTransactionHelper>())
{
}
public LoggingNHibernateSessionAttribute(
IActionLogHelper actionLogHelper,
IActionExceptionHandler actionExceptionHandler,
IActionTransactionHelper actionTransactionHelper)
{
_actionLogHelper = actionLogHelper;
_actionExceptionHandler = actionExceptionHandler;
_actionTransactionHelper = actionTransactionHelper;
}
public override void OnActionExecuting(ActionExecutingContext actionExectingContext)
{
_actionLogHelper.LogEntry(actionExectingContext.ActionDescriptor);
_actionTransactionHelper.BeginTransaction();
}
public override void OnActionExecuted(ActionExecutedContext actionExecutedContext)
{
_actionTransactionHelper.EndTransaction(actionExecutedContext);
_actionTransactionHelper.CloseSession();
_actionExceptionHandler.HandleException(actionExecutedContext);
_actionLogHelper.LogExit(actionExecutedContext.ActionDescriptor);
}
}
运行应用程序时,我可以在数据库中保存一个实体。但当我点击刷新按钮并抛出异常时,表示会话已关闭
我不知道为什么会这样。(我搜索并找到了这个,但无法解决我的问题)
在我的NinjectConfigurator中,我将inRequestScope()添加到了所有注入中,但没有得到响应。我在刷新页面时已选中,将打开该页面会话。但我不知道为什么说会议结束了
更新:
当我第一次运行应用程序时。我可以创建一个新成员。但当我点击刷新按钮时,会话将意外关闭!!
首次运行:
Zip格式:这里一个非常重要的事情,可能是NHibernate的性质。NHibernate及其
会话在ASP.NET MVC中的寿命更长,这是可以预料的。我的意思是不仅仅是在
- 动作执行(控制器动作开始)
- ActionExecuted(调用视图或重定向)
实际上,会话还必须经历渲染阶段。因为,我们可以在“Action()”中加载一些代理,但它的集合只能在视图
呈现期间延迟加载。因此,即使在这些阶段,也必须打开会话
(从请求开始的同一个会话)
- ResultExecuting(只能在此处开始加载代理)
- ResultExecuted(几乎全部完成,让我们关闭会话)
换句话说在整个请求过程中保持会话打开。从授权到呈现内容
注意:另一个提示,为了确保一切正常,我正在使用这个场景(也许您也这样做):
客户端窗体将要将数据发送到服务器。方法是POST,操作是Update()
发送表单到服务器,触发Action Update()-所有事务都已就绪(如上所述)
一旦NHibernate将数据持久化到数据库中,Update()操作将结束,并重定向到操作
Detail()
如果一切正常或
Edit()
如果出现问题
用户浏览器已重定向到“操作详细信息”或“编辑”。因此,如果用户刷新,则会刷新细节或编辑。根本不调用Update()
(这是一个POST方法)
事实上,这是第一步。是操作详细信息
或编辑
之一。在这种情况下,我们已经面临这个问题了…您有这个错误,因为Asp.Net MVC不会为每个请求创建一个新的LoggingHbernateSessionAttribute实例。它会在您第一次请求操作时创建一个新实例,然后在将来使用这个实例
其行为如下:
第一次调用Post
->“LoggingNHibernateSession”的新实例已创建
第一次调用Put
->创建另一个“LoggingNHibernateSession”实例
第二次调用上一步中的“LoggingNHibernateSession”实例
第一次调用Delete
->创建另一个“LoggingNHibernateSession”实例
[LoggingNHibernateSession]
public JsonResult Post(Dto data)
{
/* ... */
}
[LoggingNHibernateSession]
public JsonResult Put(int id, Dto data)
{
/* ... */
}
[LoggingNHibernateSession]
public JsonResult Delete(int id)
{
/* ... */
}
可以使用Func
而不是构造函数中的IActionLogHelper
来解决此问题。可以在OnActionExecuting
方法中初始化IActionLogHelper
的实例
public class LoggingNHibernateSessionAttribute : ActionFilterAttribute
{
/* your code */
private readonly Func<IActionTransactionHelper> _getActionTransactionHelper;
private IActionTransactionHelper _actionTransactionHelper;
public LoggingNHibernateSessionAttribute()
: this(WebContainerManager.Get<IActionLogHelper>(),
WebContainerManager.Get<IActionExceptionHandler>(),
() => WebContainerManager.Get<IActionTransactionHelper>())
{
}
public LoggingNHibernateSessionAttribute(
IActionLogHelper actionLogHelper,
IActionExceptionHandler actionExceptionHandler,
Func<IActionTransactionHelper> getActionTransactionHelper)
{
_actionLogHelper = actionLogHelper;
_actionExceptionHandler = actionExceptionHandler;
_getActionTransactionHelper = getActionTransactionHelper;
_actionTransactionHelper = null;
}
public override void OnActionExecuting(ActionExecutingContext actionExectingContext)
{
_actionTransactionHelper = _getActionTransactionHelper();
_actionLogHelper.LogEntry(actionExectingContext.ActionDescriptor);
_actionTransactionHelper.BeginTransaction();
}
/* your code */
}
公共类LoggingHibernateSessionAttribute:ActionFilterAttribute
{
/*你的代码*/
私有只读函数_getActionTransactionHelper;
私有IActionTransactionHelper\u actionTransactionHelper;
公共日志JubernateSessionAttribute()
:此(WebContainerManager.Get(),
WebContainerManager.Get(),
()=>WebContainerManager.Get())
{
}
公共日志HibernateSessionAttribute(
IActionLogHelper操作LogHelper,
IActionExceptionHandler actionExceptionHandler,
Func getActionTransactionHelper)
{
_actionLogHelper=actionLogHelper;
_actionExceptionHandler=actionExceptionHandler;
_getActionTransactionHelper=getActionTransactionHelper;
_actionTransactionHelper=null;
}
公共覆盖无效OnActionExecuting(ActionExecutingContext ActionExecutingContext)
{
_actionTransactionHelper=\u getActionTransactionHelper();
_actionLogHelper.LogEntry(ActionExecutingContext.ActionDescriptor);
_actionTransactionHelper.BeginTransaction();
}
public class LoggingNHibernateSessionAttribute : ActionFilterAttribute
{
/* your code */
private readonly Func<IActionTransactionHelper> _getActionTransactionHelper;
private IActionTransactionHelper _actionTransactionHelper;
public LoggingNHibernateSessionAttribute()
: this(WebContainerManager.Get<IActionLogHelper>(),
WebContainerManager.Get<IActionExceptionHandler>(),
() => WebContainerManager.Get<IActionTransactionHelper>())
{
}
public LoggingNHibernateSessionAttribute(
IActionLogHelper actionLogHelper,
IActionExceptionHandler actionExceptionHandler,
Func<IActionTransactionHelper> getActionTransactionHelper)
{
_actionLogHelper = actionLogHelper;
_actionExceptionHandler = actionExceptionHandler;
_getActionTransactionHelper = getActionTransactionHelper;
_actionTransactionHelper = null;
}
public override void OnActionExecuting(ActionExecutingContext actionExectingContext)
{
_actionTransactionHelper = _getActionTransactionHelper();
_actionLogHelper.LogEntry(actionExectingContext.ActionDescriptor);
_actionTransactionHelper.BeginTransaction();
}
/* your code */
}