Search code examples
c#.netazure-functionsmiddlewarehttpresponse

How to get HttpResponseData in middleware after executing the Azure function?


Hi i'm trying to print in console the HttpRequestData and the HttpResponseData using a middleware for azure functions (Isolated).

I can get correctly the value for HttpRequestData but the value for response is ever empty "".

My Middleware:

 public class HistoryLogMiddleware : IFunctionsWorkerMiddleware
 {
   public HistoryLogMiddleware() { }

   public async Task Invoke(FunctionContext context, FunctionExecutionDelegate next)
   {
     var requestData = await context.GetHttpRequestDataAsync();
     var body = await new StreamReader(requestData.Body).ReadToEndAsync();

     Console.WriteLine($"Request Body: {body}");

     requestData.Body.Position = 0;

     await next(context);   
     
     var responseData = context.GetInvocationResult();
     if(responseData != null && responseData.Value is HttpResponseData) 
     {
         var responseFormat = (HttpResponseData)responseData.Value;
         var responseBody = await new StreamReader(responseFormat.Body).ReadToEndAsync();
         Console.WriteLine($"Response Body: {responseBody}");

         responseFormat.Body.Position = 0;
     }

   }
 }

My example function:

 [Function(nameof(RegisterClientFunction))]
 public async Task<HttpResponseData> RunAsync(
 [HttpTrigger(AuthorizationLevel.Function, "post")] HttpRequestData req)
 {
   string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
   var data = JsonConvert.DeserializeObject<RegisterClientRequest>(requestBody);

   var respDomain = await ExecuterDomain.ExecuteAsync(() => _clientsDomain.RegisterClient(data));

   var response = req.CreateResponse((HttpStatusCode)respDomain.Status);
   response.Headers.Add("Content-Type", "text/plain; charset=utf-8");
   await response.WriteStringAsync(JsonConvert.SerializeObject(respDomain).ToString(), Encoding.UTF8);

   return response;
}

console doesn't show httpresponsedata

Does anybody know how to get the response value in the middleware ?


Solution

  • You can get the response body by making few modification in HistoryLogMiddleware file.

    I am able to get the the response body by using below code-

    using Azure;
    using Microsoft.Azure.Functions.Worker;
    using Microsoft.Azure.Functions.Worker.Http;
    using Microsoft.Azure.Functions.Worker.Middleware;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace _78438359
    {
        public class HistoryLogMiddleware : IFunctionsWorkerMiddleware
        {
            public HistoryLogMiddleware() { }
    
            public async Task Invoke(FunctionContext context, FunctionExecutionDelegate next)
            {
                var requestData = await context.GetHttpRequestDataAsync();
                var body = await new StreamReader(requestData.Body).ReadToEndAsync();
    
                Console.WriteLine($"Request Body: {body}");
    
                requestData.Body.Position = 0;
    
                await next(context);
    
                var response = context.GetHttpResponseData();
                if (response != null)
                {
                    var responseBody = await GetResponseContentAsync(response);
                    Console.WriteLine($"Response Body: {responseBody}");
                }
            }
            private async Task<string> GetResponseContentAsync(HttpResponseData response) 
            { 
                string stringResp = string.Empty; 
                if (response.Body != null) 
                { 
                    response.Body.Position = 0; 
                    stringResp = await new StreamReader(response.Body).ReadToEndAsync(); 
                } 
                return stringResp; 
            }
        }
    }
    

    I have below code in RegisterClientFunction file.

    using Microsoft.Azure.Functions.Worker;
    using Microsoft.Azure.Functions.Worker.Http;
    using Microsoft.Extensions.Logging;
    using Newtonsoft.Json;
    using System.Net;
    using System.Text;
    
    namespace _78438359
    {
        public class RegisterClientFunction
        {
            public RegisterClientFunction() { }
    
            [Function(nameof(RegisterClientFunction))]
            public async Task<HttpResponseData> RunAsync(
              [HttpTrigger(AuthorizationLevel.Anonymous, "post")] HttpRequestData req)
            {
                string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
                var data = JsonConvert.DeserializeObject<RegisterClientRequest>(requestBody);
    
                var response = req.CreateResponse(HttpStatusCode.OK);
                response.Headers.Add("Content-Type", "text/plain; charset=utf-8");
                await response.WriteStringAsync("Client registered successfully.", Encoding.UTF8);
    
                return response;
            }
        }
    }
    

    I am able to get the expected response as shown below-

    enter image description here

    Azure Functions Core Tools
    Core Tools Version:       4.0.5700 Commit hash: N/A +71cc84964a60bfb07d95839b7c666bd239507bdd (64-bit)
    Function Runtime Version: 4.33.2.22572
    
    [2024-05-09T03:26:15.626Z] Found C:\Users\******\78438359\78438359\78438359.csproj. Using for user secrets file configuration.
    [2024-05-09T03:26:23.593Z] Azure Functions .NET Worker (PID: 13132) initialized in debug mode. Waiting for debugger to attach...
    [2024-05-09T03:26:23.677Z] Worker process started and initialized.
    
    Functions:
    
            RegisterClientFunction: [POST] http://localhost:7295/api/RegisterClientFunction
    
    For detailed output, run func with --verbose flag.
    [2024-05-09T03:26:28.922Z] Host lock lease acquired by instance ID '000000000000000000000000BF6D1ED5'.
    [2024-05-09T03:27:02.991Z] Executing 'Functions.RegisterClientFunction' (Reason='This function was programmatically called via the host APIs.', Id=87bf48e4-8ca8-4cbe-a6c0-f8a69c0ad39c)
    [2024-05-09T03:27:03.354Z] Request Body: {
    [2024-05-09T03:27:03.357Z]     "Name": "Afreen"
    [2024-05-09T03:27:03.359Z] }
    [2024-05-09T03:27:03.710Z] Response Body: Client registered successfully.
    [2024-05-09T03:27:03.951Z] Executed 'Functions.RegisterClientFunction' (Succeeded, Id=87bf48e4-8ca8-4cbe-a6c0-f8a69c0ad39c, Duration=1022ms)