Jithesh Balakrishnan
Jithesh Balakrishnan

Reputation: 82

Telemetry Initializer to add request body content from .net core MVC app to request telemetry properties not working

I'm trying to integrate application insights to .net core MVC application. Everything worked as expected till I added a telemetry initializer to read request body content. I created a ITelemetryInitializer which reads the content from the request body if the telemetry type is request telemetry. But i'm getting "System.ObjectDisposedException: 'Cannot access a disposed object.'"

Issue:

On debugging I noticed, when a POST/PUT http call is made, MVC action method is invoked before Initialize() method. So by the time the Initialize() method is invoked, request body request stream is already disposed. I've a similar implementation for 4.6 framework web api application, but its works fine without this issue.

Is there a way I can invoke the initializers before MVC action is executed. I tried configuring application insights with IWebHostBuilder and IServiceCollection.

Did anyone come across this issue?

Version Info SDK Version : 2.2.1 .NET Version : .Net core 2.0 How Application was onboarded with SDK(VisualStudio/StatusMonitor/Azure Extension) : OS : Hosting Info (IIS/Azure WebApps/ etc) : IIS

Update (copied code from comment):

if (!(telemetry is RequestTelemetry requestTelemetry))
   return;
var request = _httpContextAccessor.HttpContext?.Request;
if (request == null)
   return;
if (request.Body.CanRead)
{
   request.EnableRewind();
   using (var memoryStream = new MemoryStream())
   { 
      request.Body.CopyTo(memoryStream);
      request.Body.Position = 0; //add to telemetry properties
   }
}

Upvotes: 2

Views: 3526

Answers (1)

cijothomas
cijothomas

Reputation: 3126

I replied to your post in Github as well. Here's the correct way of enriching telemetry with information from Http Post/Put request body. This is a controller Post Action, and the RequestTelemetry is enriched with information from the post body.

[HttpPost]
        public IActionResult Create([FromBody] TodoItem item)
        {
            if (item == null)
            {
                return BadRequest();
            }

            RequestTelemetry requestTelemetry = HttpContext.Features.Get<RequestTelemetry>();
            requestTelemetry.Properties.Add("nameFromBody", item.Name);

            _context.TodoItems.Add(item);
            _context.SaveChanges();

            return CreatedAtRoute("GetTodo", new { id = item.Id }, item);
        }

Upvotes: 3

Related Questions