我已经实现了ActionFilterAttribute
负责NHibernate事务管理。事务在OnResultedExecuted
覆盖中提交,偶尔会导致抛出异常。
我能够成功拦截控制器OnException
覆盖中的这些异常,但页面仍会重定向,就像事务成功一样。
我希望能够做的是返回导致错误的相同视图操作,并将异常消息添加到ModelState
。
我尝试了很多不同的东西,但似乎都没有用。这是我最近的尝试:
[HttpPost]
[Transaction]
[HandleError]
public ActionResult Enroll(EnrollNewEmployeeCommand command)
{
if(command.IsValid())
{
try
{
_commandProcessor.Process(command);
}
catch(Exception exception)
{
ModelState.AddModelError("", exception.Message);
return View(command);
}
return this.RedirectToAction(x => x.Index()); // redirects to index even if an error occurs
}
return View(command);
}
protected override void OnException(ExceptionContext filterContext)
{
//dont interfere if the exception is already handled
if (filterContext.ExceptionHandled)
return;
ModelState.AddModelError("", filterContext.Exception.Message);
filterContext.ExceptionHandled = true;
// want to return original view with updated modelstate
filterContext.Result = new ViewResult
{
ViewName = filterContext.RequestContext.RouteData.Values["action"].ToString(),
ViewData = filterContext.Controller.ViewData
};
}
答案 0 :(得分:4)
我希望能够做的是返回导致错误的相同视图操作,并将异常消息添加到ModelState
你做不到。 OnResultedExecuted
发生得太晚了。视图呈现已结束,您无法再修改此阶段将发送给客户端的内容。
如果您希望仍然能够将返回的结果修改为客户端,那么您的最后一次机会是OnResultExecuting
。所以你可以在那里提交你的交易。我猜不会那么惩罚。
相反,我甚至会在OnActionExecuted
事件中提交事务,因为在这个阶段你所拥有的应该是一个完全初始化的视图模型传递给视图进行渲染。这就是你的交易边界应该结束的地方。应该从任何事务和数据库内容中排除呈现视图的过程。它只是从视图模型中呈现的HTML(或其他东西),简单明了。