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

73
4

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


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


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


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

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


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

спросил(а) 2021-01-14T11:13:16+03:00 1 месяц, 1 неделя назад
1
Решение
95

Все фильтры действий имеют свойство 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 ничего не делать.

ответил(а) 2021-01-14T11:13:16+03:00 1 месяц, 1 неделя назад
85

Если ваш 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
}
}

ответил(а) 2021-01-14T11:13:16+03:00 1 месяц, 1 неделя назад
43

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


HTHS,

Чарльз

ответил(а) 2021-01-14T11:13:16+03:00 1 месяц, 1 неделя назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема