Tony Riddle
Tony Riddle

Reputation: 33

Replacing Request/Response Body in asp.net core middleware

I want to replace the request/response body in my middleware. Suppose if client sends Hello, I want to change it to Hola and similarly with response. I found the code that works but not to my requirement. My question is why this works and the other do not. It is actually the same code.

Working Code

public async Task InvokeAsync(HttpContext context, RequestDelegate next)
       {
            var request = context.Request;
            var stream = request.Body;// currently holds the original stream                    
            var originalReader = new StreamReader(stream);
            var originalContent = await originalReader.ReadToEndAsync();
            var notModified = true;
            try
            {

                if (originalContent != null)
                {
                    //Master is some model name
                    var modifiedData = new Master() { Id = "Changed in Middleware", Email = "Changed" };
                    var json = JsonConvert.SerializeObject(modifiedData);
                    //json variable is just a string here
                    //modified stream
                    var requestData = Encoding.UTF8.GetBytes(json);
                    stream = new MemoryStream(requestData);
                    notModified = false;
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
            if (notModified)
            {
                //putting original data
                var requestData = Encoding.UTF8.GetBytes(originalContent);
                stream = new MemoryStream(requestData);
            }

            request.Body = stream;
            
            await next(context);
        }

Not working Code But My Requirement

public async Task InvokeAsync(HttpContext context, RequestDelegate next)
       {
            var request = context.Request;
            var stream = request.Body;// currently holds the original stream                    
            var originalReader = new StreamReader(stream);
            var originalContent = await originalReader.ReadToEndAsync();
            var notModified = true;
            try
            {

                if (originalContent != null)
                {
                    var json = "This is just a string as deserializing returns string";
                    //modified stream
                    var requestData = Encoding.UTF8.GetBytes(json);
                    stream = new MemoryStream(requestData);
                    notModified = false;
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
            if (notModified)
            {
                //putting original data
                var requestData = Encoding.UTF8.GetBytes(originalContent);
                stream = new MemoryStream(requestData);
            }

            request.Body = stream;
            
            await next(context);
        }

So the working code pass on the changes to the controller, and has value Id ="Changed in middlware" and Email = "changed" but the not working code doesnt pass anything ... in the controller, argument has null and not the "This is just a string as deserializing returns string" value. I know this is not some magic happening. Am i missing something?

Upvotes: 1

Views: 6100

Answers (1)

Yiyi You
Yiyi You

Reputation: 18139

You need to convert string to jsontype.Try to change your code like this:

public async Task InvokeAsync(HttpContext context, RequestDelegate next)
   {
        var request = context.Request;
        var stream = request.Body;// currently holds the original stream                    
        var originalReader = new StreamReader(stream);
        var originalContent = await originalReader.ReadToEndAsync();
        var notModified = true;
        try
        {

            if (originalContent != null)
            {
                var str = "This is just a string as deserializing returns string";
                //convert string to jsontype
                var json = JsonConvert.SerializeObject(str);
                //modified stream
                var requestData = Encoding.UTF8.GetBytes(json);
                stream = new MemoryStream(requestData);
                notModified = false;
            }
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
        }
        if (notModified)
        {
            //putting original data
            var requestData = Encoding.UTF8.GetBytes(originalContent);
            stream = new MemoryStream(requestData);
        }

        request.Body = stream;
        
        await next(context);
    }

TestRequestBody Action:

public IActionResult TestRequestBody([FromBody] string s)
        {

            return Ok();
        }

result: enter image description here

Upvotes: 1

Related Questions