c # Атрибуты и переопределение поведения asp.net mvc

2

У меня есть атрибут транзакции, который выполняет фиксацию в методе onactionexecuted.

Это указано в методе контроллера, для одного из моих действий мне нужно переопределить этот метод и не вызывать код в onactionexecuted?

Вот пример кода.

[Transaction]
public class TestController
{
    public ActionResult Index()
    {
        return View();
    }

    [NoTransaction]
    public ActionResult Test()
    {
        return View();
    }
}

Атрибут [NoTransaction] должен переопределять метод onactionexecuted в [Transaction]. Есть ли способ сделать это?

  • 1
    Пожалуйста, предоставьте код для иллюстрации вашего вопроса.
Теги:
asp.net-mvc
attributes

3 ответа

3
Лучший ответ

Если ваш NoTransactionAttribute является фильтром, вы можете установить флаг внутри своего OnActionExecuting(), как это предлагается в другом сообщении. В противном случае:

// just a marker attribute with no special logic
public sealed class NoTransactionAttribute : Attribute { }

public class TransactionAttribute : ActionFilterAttribute {
    public override void OnActionExecuted(ActionExecutedContext filterContext) {
        if (filterContext.ActionDescriptor.IsDefined(typeof(NoTransactionAttribute), true /* inherit */)
            || filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(typeof(NoTransactionAttribute), true /* inherit */) {
                return; // should skip logic
        }

        // perform your logic here
    }
}
  • 0
    Это отстой, что ActionDescriptor.IsDefined (typeof (Foo), true) на самом деле не использует наследование правильно. Например, контроллер имеет [Authorize], которое наследуется действием, но метод ActionDescriptor.IsDefined возвращает false.
4

Все фильтры действий имеют свойство order. Если он не определен, он имеет неявное значение -1. Когда фильтры имеют один и тот же порядок, порядок определяется по объему: применяется ли он к контроллеру или применяется к действию.

Фильтры с областью действия контроллера, выполненные в том же порядке, выполняются перед фильтрами действий того же порядка.

Простым обходным путем является применение явного упорядочения в этом случае к атрибуту Transaction.

[Transaction(Order=1)]
public class TestController
{
    public ActionResult Index()
    {
        return View();
    }

    [NoTransaction(Order=0)]
    public ActionResult Test()
    {
        return View();
    }
}

Это обеспечит выполнение NoTransaction до транзакции.

Если вы хотите, чтобы NoTransaction переопределило транзакцию, самое простое - добавить NoTransaction добавить специальный ключ в HttpContext.Items, который читает атрибут транзакции. Присутствие этого ключа говорит атрибуту Transaction ничего не делать.

0

В атрибуте NoTransaction OnActionExecuting вы можете поместить некоторый флаг в HttpContext.Items, который вы можете проверить в атрибуте Transaction OnActionExecuted. Или некоторые варианты.

HTHS,
Чарльз

  • 0
    [NoTransaction] запускается первым?
  • 0
    Я думаю, что порядок будет: Transaction.OnActionExecuting -> NoTransaction.OnActionExecuting -> NoTransaction.OnActionExecuted -> Transaction.OnActionExecuted

Ещё вопросы

Сообщество Overcoder
Наверх
Меню