web-dev-qa-db-fra.com

Comment enregistrer automatiquement chaque demande dans .NET Core WebAPI?

J'aimerais que chaque demande soit enregistrée automatiquement. Dans le projet précédent .NET Framwork WebAPI, j'avais l'habitude d'enregistrer un delegateHandler pour le faire.

WebApiConfig.cs

public static void Register(HttpConfiguration config)
{
    config.MessageHandlers.Add(new AutoLogDelegateHandler());
}

AutoLogDelegateHandler.cs

public class AutoLogDelegateHandler : DelegatingHandler
{

    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        var requestBody = request.Content.ReadAsStringAsync().Result;

        return await base.SendAsync(request, cancellationToken)
            .ContinueWith(task =>
            {
                HttpResponseMessage response = task.Result;

                //Log use log4net
                _LogHandle(request, requestBody, response);

                return response;
            });
    }
}

un exemple du contenu du journal:

------------------------------------------------------
2017-08-02 19:34:58,840
uri: /emp/register
body: {
    "timeStamp": 1481013427,
    "id": "0322654451",
    "type": "t3",
    "remark": "system auto reg"
}
response: {"msg":"c556f652fc52f94af081a130dc627433","success":"true"}
------------------------------------------------------

Mais dans le projet .NET Core WebAPI, il n’ya pas de WebApiConfig, ni de fonction de registre dans Global.asax GlobalConfiguration.Configure(WebApiConfig.Register);

Alors, y a-t-il un moyen d’y parvenir avec .NET Core WebAPI?

4
wtf512

Vous pouvez créer votre propre attribut de filtre ...

public class InterceptionAttribute : ActionFilterAttribute
{
  public override void OnActionExecuting(HttpActionContext actionContext)
  {
    var x = "This is my custom line of code I need executed before any of the controller actions, for example log stuff";
    base.OnActionExecuting(actionContext);
  }
}

... et vous l'enregistreriez avec GlobalFilters, mais puisque vous avez dit que vous utilisiez .NET Core, voici comment vous pouvez essayer de continuer ...

De docs.Microsoft.com

Vous pouvez enregistrer un filtre globalement (pour tous les contrôleurs et actions) En l'ajoutant à la collection MvcOptions.Filters de la méthode ConfigureServices de la classe de démarrage:

Faites-nous savoir si cela a fonctionné.

P.S. Voici un tutoriel complet sur l'interception de requêtes avec WebAPI , au cas où quelqu'un aurait besoin de plus de détails.

7
Eedoh

ActionFilter fonctionnera jusqu'à ce que vous ayez besoin de consigner only demandes traitées par le middleware MVC (en tant qu'actions du contrôleur).

Si vous avez besoin de la journalisation pour toutes les demandes entrantes, vous devez utiliser une approche middleware. 

Bon visuel explication :  enter image description here

Notez que l'ordre du middleware est important et que si votre journalisation doit être effectuée au début de l'exécution du pipeline, votre middleware doit être l'un des premiers.

Exemple simple tiré de docs :

public void Configure(IApplicationBuilder app)
    {
        app.Use(async (context, next) =>
        {
            // Do loging
            // Do work that doesn't write to the Response.
            await next.Invoke();
            // Do logging or other work that doesn't write to the Response.
        });
13
Set

Démo:

AutologArribute.cs (nouveau fichier)

/// <summary>
/// <see cref="https://docs.Microsoft.com/en-us/aspnet/core/mvc/controllers/filters#Dependency injection"/>
/// </summary>
public class AutoLogAttribute : TypeFilterAttribute
    {
        public AutoLogAttribute() : base(typeof(AutoLogActionFilterImpl))
        {

        }

        private class AutoLogActionFilterImpl : IActionFilter
        {
            private readonly ILogger _logger;
            public AutoLogActionFilterImpl(ILoggerFactory loggerFactory)
            {
                _logger = loggerFactory.CreateLogger<AutoLogAttribute>();
            }

            public void OnActionExecuting(ActionExecutingContext context)
            {
                // perform some business logic work
            }

            public void OnActionExecuted(ActionExecutedContext context)
            {
                //TODO: log body content and response as well
                _logger.LogDebug($"path: {context.HttpContext.Request.Path}"); 
            }
        }
    }

StartUp.cs

public void ConfigureServices(IServiceCollection services)
{
    //....

    // https://docs.Microsoft.com/en-us/aspnet/core/mvc/controllers/filters#filter-scopes-and-order-of-execution
    services.AddMvc(opts=> {
        opts.Filters.Add(new AutoLogAttribute());
    });

    //....
}
1
wtf512