La solution fournie par @yonisha est à mon avis le plus propre disponible. Cependant, vous avez encore besoin pour obtenir votre httpcontext là et que vous avez besoin de plus de code. J'ai également inséré quelques commentaires qui sont fondées ou prise à partir d'exemples de code ci-dessus. Il est important de rétablir la position de votre demande, sinon vous allez perdre les données.
C'est ma solution que j'ai testé et qui me donne la jsonbody:
public class RequestBodyInitializer : ITelemetryInitializer
{
readonly IHttpContextAccessor httpContextAccessor;
public RequestBodyInitializer(IHttpContextAccessor httpContextAccessor)
{
this.httpContextAccessor = httpContextAccessor;
}
public void Initialize(ITelemetry telemetry)
{
if (telemetry is RequestTelemetry requestTelemetry)
{
if ((httpContextAccessor.HttpContext.Request.Method == HttpMethods.Post ||
httpContextAccessor.HttpContext.Request.Method == HttpMethods.Put) &&
httpContextAccessor.HttpContext.Request.Body.CanRead)
{
const string jsonBody = "JsonBody";
if (requestTelemetry.Properties.ContainsKey(jsonBody))
{
return;
}
//Allows re-usage of the stream
httpContextAccessor.HttpContext.Request.EnableRewind();
var stream = new StreamReader(httpContextAccessor.HttpContext.Request.Body);
var body = stream.ReadToEnd();
//Reset the stream so data is not lost
httpContextAccessor.HttpContext.Request.Body.Position = 0;
requestTelemetry.Properties.Add(jsonBody, body);
}
}
}
Alors assurez-vous également d'ajouter à votre Démarrage -> ConfigureServices
services.AddSingleton<ITelemetryInitializer, RequestBodyInitializer>();
EDIT:
Si vous aussi vous voulez obtenir le responsebody j'ai trouvé utile d'en créer un morceau de middleware (dotnet de base ne savez pas sur le cadre). Au début, j'ai eu approche ci-dessus où vous vous connectez une réponse et une demande, mais la plupart du temps, vous voulez que ces ensemble.
public async Task Invoke(HttpContext context)
{
var reqBody = await this.GetRequestBodyForTelemetry(context.Request);
var respBody = await this.GetResponseBodyForTelemetry(context);
this.SendDataToTelemetryLog(reqBody, respBody, context);
}
On attend à la fois une Demande et une Réponse où la demande est à peu près la même que ci-dessus, au lieu que c'est une tâche.
Pour le corps de la réponse, j'ai utilisé le code ci-dessous, j'ai également exclu un 204 depuis qui conduit à une nullref:
public async Task<string> GetResponseBodyForTelemetry(HttpContext context)
{
Stream originalBody = context.Response.Body;
try
{
using (var memStream = new MemoryStream())
{
context.Response.Body = memStream;
//await the responsebody
await next(context);
if (context.Response.StatusCode == 204)
{
return null;
}
memStream.Position = 0;
var responseBody = new StreamReader(memStream).ReadToEnd();
//make sure to reset the position so the actual body is still available for the client
memStream.Position = 0;
await memStream.CopyToAsync(originalBody);
return responseBody;
}
}
finally
{
context.Response.Body = originalBody;
}
}