2017-09-14 3 views
1

Je cherche à créer un filtre implémentant IAsyncActionFilter qui récupérera les données du contexte ActionParameters du contexte de la requête en cours et de Result. J'utilise un attribut personnalisé MyLogAttribute pour diriger le comportement de journalisation, par ex. d'activer la journalisation et d'indiquer les champs avec des informations critiques.ASP.NET Core AsyncActionFilter pour enregistrer ActionArguments et Résultat

public class AsyncMyLogFilter : IAsyncActionFilter 
{ 
    public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) 
    { 
     var actionDescriptor = context.ActionDescriptor as ControllerActionDescriptor; 

     if (actionDescriptor != null) 
     { 
      var attribute = actionDescriptor.MethodInfo.GetCustomAttribute<MyLogAttribute>(); 

      if (attribute != null) 
      { 

       await next(); 

       // This is where the magic is supposed to happen: 
       LoggerHelper.Log(context.ActionArguments, context.Result); 
      } 

      return; 
     } 

     await next(); 
    } 
} 

La façon dont le filtre fournit un délégué next() m'a amené à croire que le passé ce moment-là l'action sera terminée et l'objet de résultat disponible pour comme ObjectResult inspection. Cependant, alors que le filtre est capable de saisir le ActionArguments sans problème, la propriété Result est malheureusement juste nulle, ce qui n'est pas utile du tout.

L'alternative évidente, la IActionFilter synchrone, me permet d'examiner l'objet Result sur la scène OnActionExecuted, mais à ce stade, le dictionnaire ActionArguments n'est pas disponible.

Donc, y a-t-il un moyen d'accéder à la fois à ActionArguments et à Result dans la même portée de méthode?

S

+0

Les arguments non disponibles sur 'ActionExecutedContext.ActionDescriptor.Parameters'? –

+0

La collection Parameters inclut les noms et les types des paramètres, mais ne semble pas contenir leurs valeurs. –

Répondre

0

Bien que le problème sous sa forme d'origine n'a pas été résolu, j'ai pu créer une solution de contournement avec un IActionFilter:

public class ActivityLogFilter : IActionFilter 
{ 
    public void OnActionExecuting(ActionExecutingContext context) 
    { 
     var actionDescriptor = context.ActionDescriptor as ControllerActionDescriptor; 

     if (actionDescriptor != null) 
     { 
      var attribute = actionDescriptor.MethodInfo.GetCustomAttribute<MyLogAttribute>(); 

      if (attribute != null) 
      { 
       context.HttpContext.Items["MyLogData"] = GetRelevantLogData(context.ActionArguments); // Apply some custom logic to select relevant log data 
      } 
     } 

     public void OnActionExecuted(ActionExecutedContext context) 
     { 
      var actionDescriptor = context.ActionDescriptor as ControllerActionDescriptor; 

      if (actionDescriptor != null) 
      { 
       var attribute = actionDescriptor.MethodInfo.GetCustomAttribute<MyLogAttribute>(); 

       if (attribute != null) 
       { 
        var actionParametersData = (MyActionParametersLogData)context.HttpContext.Items["MyLogData"] 

        LoggerHelper.Log(actionParametersData, context.Result); 
       } 
      } 
     } 
    } 
} 

science des fusées Pas exactement; il semble un peu fragile ("Que faire si mes articles HttpContext disparaissent !?"), mais il semble faire le travail.

S