我正在删除这样的内容:
[Transaction]
[AcceptVerbs(HttpVerbs.Post)]
public RedirectToRouteResult DeleteQualitativeGlobalFeatureValue(string Id)
{
try
{
BlaService.DeleteBla(Id);
}
catch (Exception e)
{
ModelState.AddModelError("Exception", e.Message);
}
return RedirectToAction("Bladibla", new { Id = FeatureId });
}
但是,如果某些内容被“非法”删除(例如导致违反引用约束),我会收到一个可怕的异常,而这个异常并不会被我的try catch块捕获。我认为这与[Transaction]属性有关。如何避免这种情况在控制器方法中捕获任何异常?
感谢。
祝福,
基督教
答案 0 :(得分:1)
这是因为实际提交和数据库端验证在事务提交时发生。
您可以使用自己的,稍微修改过的Sharp属性版本。
public class TransactionAttribute: ActionFilterAttribute
{
private TransactionAttributeHelper helper = new TransactionAttributeHelper();
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
helper.BeginTransaction();
}
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
try
{
// notice that I rollback both on exception and model error, this helps a lot
helper.FinishTransaction(filterContext.Exception == null &&
filterContext.Controller.ViewData.ModelState.IsValid);
}
catch (Exception ex)
{
// here add ModelError, return error, or redirect
}
}
}
TransactionAttributeHelper放置在.Data程序集中以避免.Controllers中的NHibernate引用。
public class TransactionAttributeHelper
{
public void BeginTransaction()
{
NHibernateSession.CurrentFor(GetEffectiveFactoryKey()).BeginTransaction();
}
public void FinishTransaction(bool commit)
{
string effectiveFactoryKey = GetEffectiveFactoryKey();
ITransaction currentTransaction =
NHibernateSession.CurrentFor(effectiveFactoryKey).Transaction;
if (currentTransaction.IsActive)
{
if (commit)
{
currentTransaction.Commit();
}
else
{
currentTransaction.Rollback();
}
}
}
private static string GetEffectiveFactoryKey()
{
return NHibernateSession.DefaultFactoryKey;
}
}
或者,当然,您可以使用repository.DbContext.BeginTransaction / Commit / etc方法进行不带属性的转换,并手动捕获/处理错误。但是上述方法可以避免许多这样的手工工作。
答案 1 :(得分:0)
您应该查看实现IExceptionFilter接口的属性。例如,System.Web.Mvc.HandleErrorAttribute可以显示异常的备用视图,并为该视图提供对异常的访问权限。如果要以不同方式处理事物或使用log4net或Elmah记录异常,您还可以创建自己的实现IExceptionFilter的属性。
即使在TransactionAttribute的代码中发生异常,在方法上使用IExceptionFilter属性也会捕获异常。