J'utilise Microsoft Asp.net WebApi2 hébergé sur IIS. J'aimerais très simplement consigner le corps de la demande (xml ou json) et le corps de la réponse pour chaque message.
Il n'y a rien de spécial à propos de ce projet ou du contrôleur traitant la publication. L'utilisation de structures de journalisation telles que nLog, elmah, log4net ou les fonctions de traçage intégrées de webapi ne m'intéresse pas, à moins que cela ne soit nécessaire.
Je veux simplement savoir où placer mon code de journalisation et comment obtenir le json ou le xml à partir des requêtes et réponses entrantes et sortantes.
Ma méthode de post de contrôleur:
public HttpResponseMessage Post([FromBody])Employee employee)
{
if (ModelState.IsValid)
{
// insert employee into to database
}
}
Je recommanderais d'utiliser un DelegatingHandler
. Dans ce cas, vous n'aurez plus à vous soucier du code de journalisation de vos contrôleurs.
public class LogRequestAndResponseHandler : DelegatingHandler
{
protected override async Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request, CancellationToken cancellationToken)
{
// log request body
string requestBody = await request.Content.ReadAsStringAsync();
Trace.WriteLine(requestBody);
// let other handlers process the request
var result = await base.SendAsync(request, cancellationToken);
if (result.Content != null)
{
// once response body is ready, log it
var responseBody = await result.Content.ReadAsStringAsync();
Trace.WriteLine(responseBody);
}
return result;
}
}
Il suffit de remplacer Trace.WriteLine
avec votre code de connexion et enregistrez le gestionnaire dans WebApiConfig
comme ceci:
config.MessageHandlers.Add(new LogRequestAndResponseHandler());
Il existe plusieurs approches pour gérer de manière générique la journalisation des demandes/réponses pour chaque appel de méthode WebAPI:
ActionFilterAttribute
: On peut écrire ActionFilterAttribute
personnalisé et décorer les méthodes contrôleur/action pour activer la journalisation.
Contre: Vous devez décorer chaque contrôleur/méthode (vous pouvez toujours le faire sur le contrôleur de base, mais cela ne résout pas le problème des problèmes transversaux.
Remplacez BaseController
et gérez la journalisation à cet endroit.
Con: Nous attendons/obligeant les contrôleurs à hériter d'un contrôleur de base personnalisé.
Utiliser DelegatingHandler
.
Avantage: nous ne touchons pas contrôleur/méthode ici avec cette approche. Le gestionnaire de délégation est isolé et gère normalement la consignation des demandes/réponses.
Pour un article plus détaillé, référez-vous à ceci http://weblogs.asp.net/fredriknormen/log-message-request-and-response-in-asp-net-webapi .
Une de vos options consiste à créer un filtre d'action et à en décorer votre WebApiController/ApiMethod.
Attribut de filtre
public class MyFilterAttribute : System.Web.Http.Filters.ActionFilterAttribute
{
public override void OnActionExecuting(HttpActionContext actionContext)
{
if (actionContext.Request.Method == HttpMethod.Post)
{
var postData = actionContext.ActionArguments;
//do logging here
}
}
}
Contrôleur WebApi
[MyFilterAttribute]
public class ValuesController : ApiController{..}
ou
[MyFilterAttribute]
public void Post([FromBody]string value){..}
J'espère que cela t'aides.
Obtenir l'accès au message de demande est facile. Votre classe de base, ApiController
contient .Request
propriété , qui, comme son nom l’indique, contient la requête sous forme analysée. Il vous suffit de l'examiner pour rechercher tout ce que vous souhaitez journaliser et de le transférer à votre centre de journalisation, quel qu'il soit. Ce code que vous pouvez mettre au début de votre action, si vous devez le faire pour un seul ou plusieurs.
Si vous devez le faire pour toutes les actions (toutes signifiant plus qu'une poignée gérable), vous pouvez alors remplacer .ExecuteAsync
méthode pour capturer chaque appel d’action pour votre contrôleur.
public override Task<HttpResponseMessage> ExecuteAsync(
HttpControllerContext controllerContext,
CancellationToken cancellationToken
)
{
// Do logging here using controllerContext.Request
return base.ExecuteAsync(controllerContext, cancellationToken);
}