How to read the HTTP Body in an IIS Managed Module without breaking an ASP.NET Core Azure Web App?

Shemesh, Tchelet 35 Reputation points
2026-07-09T15:37:38.7866667+00:00

I am trying to intercept and read incoming HTTP traffic using a custom managed .NET module (IHttpModule) on a Windows-based Azure Web App.

I am able to successfully fetch the context.Request and context.Response parameters, headers, and metadata. However, I cannot fetch the request body without breaking the downstream application flow.

The Architecture:

  • Host: Windows Azure Web App (IIS)
  • Interceptor: Classic IIS Managed .NET Module (NonameAzureWebAppModule)
  • Backend Application: ASP.NET Core application (AzureRedirectApp.dll) hosted In-Process.

Attached the Noname Azure Web App Module code and the web.config.

Thank you in advance for your help!

web.config.txt
NonameAzureWebAppModule.cs.txt

Developer technologies | C#
Developer technologies | C#

An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.


Answer accepted by question author

Tom Tran (WICLOUD CORPORATION) 5,625 Reputation points Microsoft External Staff Moderator
2026-07-10T03:25:11.5066667+00:00

Hi @Shemesh, Tchelet ,

Looking at your setup, I would move the request body reading into the ASP.NET Core app rather than doing it from the classic IHttpModule.

The main reason is that IIS managed modules do not handle ASP.NET Core requests the same way they handle ASP.NET Framework requests. For ASP.NET Core apps, Microsoft points to ASP.NET Core middleware as the replacement approach for these kinds of scenarios: IIS modules with ASP.NET Core.

If you can update AzureRedirectApp, you can add middleware early in the pipeline and enable buffering before reading the body:

app.Use(async (context, next) =>
{
    context.Request.EnableBuffering();

    string requestBody;

    using (var reader = new StreamReader(
        context.Request.Body,
        Encoding.UTF8,
        detectEncodingFromByteOrderMarks: false,
        leaveOpen: true))
    {
        requestBody = await reader.ReadToEndAsync();
    }

    context.Request.Body.Position = 0;

    // Store or forward requestBody as needed.

    await next();
});

The important parts are EnableBuffering() and resetting Request.Body.Position back to 0. EnableBuffering() allows the body to be read more than once, and resetting the position lets the rest of the application read the body normally afterward: EnableBuffering method.

For a setup where AzureRedirectApp cannot be modified, I do not see a Microsoft-documented approach that allows a classic managed IHttpModule to read the request body reliably without affecting the ASP.NET Core request pipeline.

GetBufferedInputStream() is documented for preserving the body for downstream ASP.NET Framework processing, but I do not see documentation showing that it is supported for an ASP.NET Core app hosted through AspNetCoreModuleV2.

One thing I noticed in the attached module is that the current code still sets requestBody to an empty string, so the body-reading code that caused the downstream issue does not appear to be included in the attachment.

One other part worth reviewing is PreSendRequestHeaders. Microsoft advises against using this event in a managed IHttpModule because it can cause issues with asynchronous requests: PreSendRequestHeaders event.

If you found my response helpful, I would greatly appreciate it if you could follow this guidance. Thank you.  

Was this answer helpful?

1 person found this answer helpful.

3 additional answers

Sort by: Most helpful
  1. Bruce (SqlWork.com) 84,856 Reputation points
    2026-07-09T17:03:15.1366667+00:00

    to capture the body, your module needs to wrap the request / response stream. but the aspnetcore module is native, and runs before managed modules. to do what you want you need to create a native module in c/c++ and register before the aspnetcore module. the other option as suggested is to use core middleware.

    Was this answer helpful?

    1 person found this answer helpful.
    0 comments No comments

  2. Deleted

    This answer has been deleted due to a violation of our Code of Conduct. The answer was manually reported or identified through automated detection before action was taken. Please refer to our Code of Conduct for more information.


    Comments have been turned off. Learn more

  3. AI answer

    2026-07-09T15:38:52.0066667+00:00

    In this architecture (IIS + ASP.NET Core app hosted via AspNetCoreModuleV2), the safest way to read the HTTP request body without breaking the downstream ASP.NET Core app is to let the ASP.NET Core middleware do the body reading, not a classic IIS managed IHttpModule.

    Key points from the platform behavior:

    1. ASP.NET Core app owns the request body processing
      • For ASP.NET Core apps behind IIS, the ASP.NET Core Module (ANCM) hands the request off to the ASP.NET Core server (IISHttpServer in-process or Kestrel out-of-process) and then into the ASP.NET Core middleware pipeline.
      • The ASP.NET Core middleware and endpoints expect to control how and when the body is read. Interfering with the body at the IIS managed-module level can consume or alter the body stream before ASP.NET Core sees it, causing downstream failures.
    2. Use ASP.NET Core middleware to inspect the body
      • The recommended pattern is to add a custom ASP.NET Core middleware early in the pipeline and read the body there.
      • Example using EnableBuffering so the body can be read multiple times:
             var builder = WebApplication.CreateBuilder(args);
             var app = builder.Build();
             
             app.Use(async (context, next) =>
             {
                 // Allow multiple reads of the request body
                 context.Request.EnableBuffering();
             
                 // Read the body (for logging/inspection)
                 await ReadRequestBody(context.Request.Body);
             
                 // Rewind so the next middleware/endpoint can read it
                 context.Request.Body.Position = 0;
             
                 await next.Invoke();
             });
             
             app.Run();
        
      • This approach ensures the ASP.NET Core app still receives the full body as expected.
    3. Prefer BodyReader for high-performance scenarios
      • For minimal APIs or other ASP.NET Core endpoints, the body can also be read via HttpRequest.BodyReader (a PipeReader), which avoids extra buffering and copies:
             app.MapPost("/uploadstream", async (IConfiguration config, HttpRequest request) =>
             {
                 var filePath = Path.Combine(config["StoredFilesPath"], Path.GetRandomFileName());
             
                 await using var writeStream = File.Create(filePath);
                 await request.BodyReader.CopyToAsync(writeStream);
             });
        
      • This is the recommended high-performance way to inspect or copy the body in ASP.NET Core.
    4. Why an IIS managed module breaks the app
      • Classic IHttpModule code (for example, handling BeginRequest, PreRequestHandlerExecute, etc.) operates in the ASP.NET/IIS pipeline before ANCM and the ASP.NET Core runtime.
      • If the module reads or buffers HttpRequest.InputStream (or similar) without correctly rewinding or preserving the body in a way compatible with ANCM, the ASP.NET Core server may see an empty or partially consumed body, leading to 500 errors or broken routing/model binding.
      • ASP.NET Core is not designed to coordinate body reading with classic ASP.NET modules; instead, it expects to be the primary consumer of the body.
    5. Practical guidance for this scenario
      • Avoid reading the request body in the IIS managed module when the site is an ASP.NET Core app.
      • Move the interception logic into ASP.NET Core middleware in the AzureRedirectApp.dll project.
      • Use HttpRequest.EnableBuffering and reset Body.Position after reading, or use BodyReader for advanced scenarios.
      • Keep the IIS module limited to headers/metadata if it must remain, and let ASP.NET Core handle the body.

    This pattern aligns with how ASP.NET Core apps are hosted behind IIS and avoids breaking the out-of-process (or in-process) ASP.NET Core Azure Web App.


    References:

    AI-generated content may be incorrect. Read our transparency notes for more information.

    Was this answer helpful?

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.