Значение CallContext, установленное в фильтре действий веб-API, не передается действию контроллера

У меня есть веб-API asp.net, где мы начинаем транзакцию, используя TransactionScope (только для POST,PUT и DELETE, но не для GET) в OnActionExecuting глобального фильтра действий, а затем завершаем или откатываем его обратно в OnActionExecuted. Недавно мы решили внести изменение, чтобы мы могли добавить SqlAzureExecutionStrategy по крайней мере для вызовов GET (поскольку он работает только при отсутствии инициированной пользователем транзакции), чтобы временные сбои могли обрабатываться для выборки данных. Я следовал этой статье здесь и реализовал то же самое в нашем приложении. Ниже приведен код.

Создан новый класс конфигурации БД

public class AzureDbConfiguration : DbConfiguration
{
    public const string CallContextKey = "SuspendExecutionStrategy";
    public AzureDbConfiguration()
    {
        this.SetExecutionStrategy("System.Data.SqlClient", () => SuspendExecutionStrategy
          ? (IDbExecutionStrategy)new DefaultExecutionStrategy()
          : new SqlAzureExecutionStrategy());   
    }

    public static bool SuspendExecutionStrategy
    {
        get
        {
            return (bool?)CallContext.LogicalGetData(CallContextKey) ?? false;
        }
        set
        {
            CallContext.LogicalSetData(CallContextKey, value);
        }
    }


}

Установка SuspendExecutionStrategy в true, когда нам нужно начать транзакцию.

public override void OnActionExecuting(HttpActionContext actionContext)
    {

        //checks if it is not a GET call
        if (RequiresTransactionInitiation(actionContext))
        {

           AzureDbConfiguration.SuspendExecutionStrategy = true;

            var transactionCompleter = new TransactionCompleter(GetDependencyScope(actionContext));
            transactionCompleter.UnitOfWork.StartTransaction(System.Data.IsolationLevel.ReadCommitted);

        }
        base.OnActionExecuting(actionContext);

    }

    public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
    {
        //checks if it is not a GET call
        if (RequiresTransactionCompletion(actionExecutedContext))
        {
            var transactionCompleter = new TransactionCompleter(GetDependencyScope(actionExecutedContext));
            if (actionExecutedContext.Exception == null)
            {

                transactionCompleter.Complete();
                AddEventsToResponseHeader(transactionCompleter.MessageTransactions.OfType<IEventTransaction>(), actionExecutedContext.Response);
            }
            else
            {
                transactionCompleter.Rollback();
            }
        //*********** line is added to just test the value of the property .This always return false.**********
         var testValue = AzureDbConfiguration.SuspendExecutionStrategy;
        }
        base.OnActionExecuted(actionExecutedContext);
    }

Проблема заключается в том, что значение SuspendExecutionStrategy установлено правильно в OnActionExecuting, но в тот момент, когда код входит в действие Controller или OnActionExecuting, оно всегда ложно.

Я провел некоторое исследование и понял, что сам контекст выполнения меняется, когда мы переходим от фильтра к действию контроллера. Поэтому, если в OnActionExecuting я проверяю Thread.CurrentThread.ExecutionContext.ToStringJson(), я вижу, что значение SuspendExecutionStrategy доступно, но если я проверяю то же самое в действии контроллера, оно недоступно, и странная часть - все остальное в контексте выполнения, все еще доступно,

Значение Thread.CurrentThread.ExecutionContext.ToStringJson() в OnActionExecuting

        {
      "LogicalCallContext": {
        "E2ETrace.ActivityID": "80000013-0003-fd00-b63f-84710c7967bb",
        "ApplicationInsights.OwinExtensions.OperationIdContext": "1c218be6-1fbb-44bf-b994-4db84115b5a3",
        "ApplicationInsights.OwinExtensions.OperationParentIdContext": "72d35ac6-a394-4205-8452-a95b36f8857a",
        "SuspendExecutionStrategy" : True
    })

Значение Thread.CurrentThread.ExecutionContext.ToStringJson() в действии контроллера и OnActionExecuted

{
      "LogicalCallContext": {
        "E2ETrace.ActivityID": "80000013-0003-fd00-b63f-84710c7967bb",
        "ApplicationInsights.OwinExtensions.OperationIdContext": "1c218be6-1fbb-44bf-b994-4db84115b5a3",
        "ApplicationInsights.OwinExtensions.OperationParentIdContext": "72d35ac6-a394-4205-8452-a95b36f8857a",
    })

Поэтому у меня возникает вопрос, как этот контекст выполнения меняется с фильтра действия на действие контроллера и почему все остальные значения в контексте выполнения все еще сохраняются.

0 ответов

Другие вопросы по тегам