本文介绍了C# DotNet 核心中间件包装响应的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我有一个简单的控制器操作,如下所示:
I have a simple controller action which looks like:
public Task<IEnumerable<Data>> GetData() { IEnumerable<Data> data = new List<Data>(); return data; }我希望能够检查中间件中的返回值,以便 JSON 看起来像
I want to be able to inspect the return value from within the middleware so the JSON would look something like
{ "data": [ ], "apiVersion": "1.2", "otherInfoHere": "here" }所以我的有效载荷总是在 data 内.我知道我可以在控制器级别执行此操作,但我不想在每个操作上都执行此操作.我宁愿在中间件中做一次.
So my payload always is within data. I know I can do this at a controller level but I don't wan to have to do it on every single action. I would rather do it in middleware once for all.
这是我的中间件示例:
public class NormalResponseWrapper { private readonly RequestDelegate next; public NormalResponseWrapper(RequestDelegate next) { this.next = next; } public async Task Invoke(HttpContext context) { var obj = context; // DO something to get return value from obj // Create payload and set data to return value await context.Response.WriteAsync(/*RETURN NEW PAYLOAD HERE*/); }有什么想法吗?
现在得到了价值,但归还为时已晚
try { using (var memStream = new MemoryStream()) { context.Response.Body = memStream; await next(context); memStream.Position = 0; object responseBody = new StreamReader(memStream).ReadToEnd(); memStream.Position = 0; await memStream.CopyToAsync(originalBody); // By now it is to late, above line sets the value that is going to be returned await context.Response.WriteAsync(new BaseResponse() { data = responseBody }.toJson()); } } finally { context.Response.Body = originalBody; } 推荐答案查看评论以了解您可以做什么来包装响应.
Review the comments to get an understanding of what you can do to wrap the response.
public async Task Invoke(HttpContext context) { //Hold on to original body for downstream calls Stream originalBody = context.Response.Body; try { string responseBody = null; using (var memStream = new MemoryStream()) { //Replace stream for upstream calls. context.Response.Body = memStream; //continue up the pipeline await next(context); //back from upstream call. //memory stream now hold the response data //reset position to read data stored in response stream memStream.Position = 0; responseBody = new StreamReader(memStream).ReadToEnd(); }//dispose of previous memory stream. //lets convert responseBody to something we can use var data = JsonConvert.DeserializeObject(responseBody); //create your wrapper response and convert to JSON var json = new BaseResponse() { data = data, apiVersion = "1.2", otherInfoHere = "here" }.toJson(); //convert json to a stream var buffer = Encoding.UTF8.GetBytes(json); using(var output = new MemoryStream(buffer)) { await output.CopyToAsync(originalBody); }//dispose of output stream } finally { //and finally, reset the stream for downstream calls context.Response.Body = originalBody; } }更多推荐
C# DotNet 核心中间件包装响应
发布评论