一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - ASP.NET教程 - 由ASP.NET Core讀取Response.Body引發的思考

由ASP.NET Core讀取Response.Body引發的思考

2023-05-08 00:02未知服務器之家 ASP.NET教程

前言 ????前幾天有群友在群里問如何在我之前的文章《ASP.NET Core WebApi返回結果統一包裝實踐》的時候有點疑問,主要的疑問點就是關于Respouse的讀取的問題。在之前的文章《深入探究ASP.NET Core讀取Request.Body的正確方式》曾分析過

前言

????前幾天有群友在群里問如何在我之前的文章《ASP.NET Core WebApi返回結果統一包裝實踐》的時候有點疑問,主要的疑問點就是關于Respouse的讀取的問題。在之前的文章《深入探究ASP.NET Core讀取Request.Body的正確方式》曾分析過關于Request的讀取問題,需要讀取Respouse的場景同樣經常遇到,比如讀取輸出信息或者包裝一下輸出結果等。無獨有偶Respouse的讀取同樣存在類似的問題,本文我們便來分析一下如何進行Response的Body讀取。

使用方式

我們在日常的使用中是如何讀取流呢?很簡單,直接使用StreamReader去讀取,方式如下

public override void OnResultExecuted(ResultExecutedContext context)
{
    //操作流之前恢復一下操作位
    context.HttpContext.Response.Body.Position = 0;

    StreamReader stream = new StreamReader(context.HttpContext.Response.Body);
    string body = stream.ReadToEnd();
    _logger.LogInformation("body content:" + body);

    context.HttpContext.Response.Body.Position = 0;
    base.OnResultExecuted(context);
}

代碼很簡單,直接讀取即可,可是這樣讀取是有問題的會拋出異常System.ArgumentException:“Stream was not readable.”異常信息就是的意思是當前Stream不可讀,也就是Respouse的Body是不可以被讀取的。關于StreamReader到底和Stream有啥關聯,我們在之前的文章深入探究ASP.NET Core讀取Request.Body的正確方式一文中有過源碼分析,這里就不在贅述了,有興趣的同學可以自行翻閱,強烈建議在閱讀本文之前可以看一下那篇文章,方便更容易了解。
如何解決上面的問題呢?方式也很簡單,比如你想在你的程序中保證Response的Body都是可讀的,你可以定義一個中間件解決這個問題。

public static IApplicationBuilder UseResponseBodyRead(this IApplicationBuilder app)
{
    return app.Use(async (context, next) =>
    {
        //獲取原始的Response Body
        var originalResponseBody = context.Response.Body;
        try
        {
            //聲明一個MemoryStream替換Response Body
            using var swapStream = new MemoryStream();
            context.Response.Body = swapStream;
            await next(context);
            //重置標識位
            context.Response.Body.Seek(0, SeekOrigin.Begin);
            //把替換后的Response Body復制到原始的Response Body
            await swapStream.CopyToAsync(originalResponseBody);
        }
        finally
        {
            //無論異常與否都要把原始的Body給切換回來
            context.Response.Body = originalResponseBody;
        }
    });
}

本質就是先用一個可操作的Stream比如咱們這里的MemoryStream替換默認的ResponseBody,讓后續對ResponseBody的操作都是針對新的ResponseBody進行操作,完成之后把替換后的ResponseBody復制到原始的ResponseBody。最終無論異常與否都要把原始的Body給切換回來。需要注意的是,這個中間件的位置盡量要放在比較靠前的位置注冊,至少也要保證在你所有要操作ResponseBody之前的位置注冊。如下所示

var app = builder.Build();
app.UseResponseBodyRead();

源碼探究

通過上面我們了解到了ResponseBody是不可以被讀取的,至于為什么呢,這個我們需要通過相關源碼了解一下。通過HttpContext類的源碼我們可以看到相關定義

public abstract class HttpContext
{
    public abstract HttpResponse Response { get; }
}

這里看到HttpContext本身是個抽象類,看一下它的屬性HttpResponse類的定義也是一個抽象類

public abstract class HttpResponse
{
}

由上面可知Response屬性是抽象的,所以抽象類HttpResponse必然包含一個子類去實現它,否則沒辦法直接操作相關方法。這里我們介紹一個網站https://source.dot.net用它可以更輕松的閱讀微軟類庫的源碼,比如CLR、ASP.NET Core、EF Core等等,雙擊一個類或者屬性方法可以查找引用和定義它們的地方,非常方便,它的源碼都是最新版本的,來源就是GitHub上的相關倉庫。找到實例化HttpResponse的為位置在HttpContext的子類DefaultHttpContext類中[點擊查看源碼

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 免费看美女被靠到爽的视频 | ova催眠性指导5最新在线 | 亚洲精品乱码蜜桃久久久 | 国产小青蛙 | 国产99精品成人免费视频 | 91精品大神国产在线播放 | 精品国产国偷自产在线观看 | 丝瓜视频黄瓜视频 | 欧美日韩精品一区二区三区视频在线 | 小早川怜子在线播放精品 | 男人肌肌捅女人 | 欧美日韩综合网在线观看 | 日本免费在线观看 | 婷婷网址 | 视频一区二区国产无限在线观看 | 午夜第一页 | 亚洲a图 | 大学生情侣在线 | 亚洲国产日韩欧美mv | 国产成人一区二区三区在线视频 | 动漫美女强行被吸乳做羞羞事 | 国产精品亚洲一区二区久久 | 波多野结衣教师未删减版 | 蜜色网| 亚洲人成在线播放 | 黑人巨大vs北条麻妃在线 | 美女尿口羞羞视频 | 国产香蕉国产精品偷在线观看 | 男女性潮高片无遮挡禁18 | 男人的天堂在线观看视频不卡 | 五月桃花网婷婷亚洲综合 | 变态女王麻麻小说在线阅读 | 母爱成瘾在线观看 | 五月天狠狠 | 国产一区二区三区福利 | 四虎影视永久在线精品免费 | 国产亚洲综合成人91精品 | 99久久无色码中文字幕 | 国内精品91久久久久 | 久久re热在线视频精6 | 夫妇交换小说全文阅读 |