0

每次我想在我的 POST 方法中使用事务时,我似乎都会重复自己。我可以使用动作过滤器或其他东西吗?

[HttpPost]
public virtual ActionResult Create(CreateModel model)
{
  if (!ModelState.IsValid)
    return View(model);

  var instruction = new Instruction(CurrentUser);
  Mapper.Map(model, instruction);

  // how do I get rid of this?
  using (var uow = _unitOfWorkFactory.Create())
  {
    _repository.Save(instruction);

    uow.SaveChanges();
  }

  return RedirectToAction("Details", new {id = instruction.Id});
}
4

1 回答 1

1

创建一个新的操作过滤器,在创建和使用 UnitOfWork 之前检查ModelState和属性:HttpContext.Error

public class TransactionalAttribute : ActionFilterAttribute
{
  private IUnitOfWork _unitOfWork;

  public override void OnActionExecuting(ActionExecutingContext filterContext)
  {
    if (filterContext.Controller.ViewData.ModelState.IsValid && filterContext.HttpContext.Error == null)
      _unitOfWork = DependencyResolver.Current.GetService<IUnitOfWork>();

    base.OnActionExecuting(filterContext);
  }

  public override void OnActionExecuted(ActionExecutedContext filterContext)
  {
    if (filterContext.Controller.ViewData.ModelState.IsValid && filterContext.HttpContext.Error == null && _unitOfWork != null)
      _unitOfWork.SaveChanges();

    base.OnActionExecuted(filterContext);
  }
}

UnitOfWork 的示例 nhibernate 实现(在您的 IoC 中注册):

public class NhibernateUnitOfWork : IUnitOfWork
{
  private readonly ISession _session;
  private ITransaction _transaction;

  public NhibernateUnitOfWork(ISession session)
  {
    _session = session;
    _transaction = session.BeginTransaction();
  }

  public void Dispose()
  {
    if (_transaction == null)
      return;

    if (!_transaction.WasCommitted)
      _transaction.Rollback();

    _transaction.Dispose();
    _transaction = null;
  }

  public void SaveChanges()
  {
    _transaction.Commit();
  }

}

用法:

[HttpPost, Transactional]
public virtual ActionResult Create(CreateModel model)
{
  if (!ModelState.IsValid)
    return View(model);

  var instruction = new Instruction(CurrentUser);
  Mapper.Map(model, instruction);
  _repository.Save(instruction);

  return RedirectToAction("Details", new {id = instruction.Id});
}

来源:http: //blog.gauffin.org/2012/06/how-to-handle-transactions-in-asp-net-mvc3/

于 2012-06-05T14:24:02.683 回答