Reputation: 33
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
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();
}
Upvotes: 1