ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

C#DotNet核心中间件包裹响应

2019-06-08 01:04:58  阅读:187  来源: 互联网

标签:c middleware net-core httpcontext


我有一个简单的控制器动作,看起来像:

    public Task<IEnumerable<Data>> GetData()
    {
        IEnumerable<Data> data = new List<Data>();
        return data;
    }

我希望能够从中间件中检查返回值,以便JSON看起来像

{
  "data": [
  ],
  "apiVersion": "1.2",
  "otherInfoHere": "here"
}

所以我的有效载荷总是在数据中.我知道我可以在控制器级别这样做,但我不想在每一个动作上都这样做.我宁愿一次性在中间件中做到这一点.

这是我的中间件的一个例子:

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;
        }

解决方法:

查看注释以了解您可以采取哪些措施来包装响应.

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,middleware,net-core,httpcontext
来源: https://codeday.me/bug/20190608/1195753.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有