2010-07-06 1 views
0

Я удалить такие вещи, как это:Transaction исключение проблема - s # агр архитектура

[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 }); 
     } 

Однако, если что-то «незаконно» исключить (например, вызывая нарушение ограничения ссылочной) я получаю ужасное исключение, которое не попадает в мой блок catch try. Я предполагаю, что это связано с атрибутом [Транзакция]. Как я могу избежать этого, чтобы поймать ЛЮБЫЕ исключения из метода контроллера?

Спасибо.

С наилучшими пожеланиями,

христианских

ответ

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, чтобы избежать NHibernate ссылки в .Controllers.

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; 
    } 
} 

В качестве альтернативы, конечно, вы можете сделать transations без атрибута с помощью repository.DbContext.BeginTransaction/Commit/и т.д. методы и ошибки улов/процесса вручную. Но вышеупомянутый подход экономит от многих таких ручных работ.

0

Вы должны изучить атрибут, реализующий интерфейс IExceptionFilter. Например, System.Web.Mvc.HandleErrorAttribute может отображать альтернативное представление для исключения и дает этому представлению доступ к исключению. Вы также можете создавать свои собственные атрибуты, которые реализуют IExceptionFilter, если вы хотите обрабатывать вещи по-другому или регистрировать исключение, используя log4net или Elmah.

Наличие атрибута IExceptionFilter для метода приведет к исключению, даже если исключение встречается в коде TransactionAttribute.

Смежные вопросы