[鐵人賽Day25] ASP.Net Core MVC 進化之路 - Response Cache(回應快取)

本篇將延續上篇的Cache主題介紹Response Cache的使用方式。

Response Cache

接下來介紹經濟又實惠的Response Cache

使用方式可分為以下兩種:

  • ResponseCacheFilterAttribute
  • Response Middleware

 

使用前記得在Startup中的ConfigureServices中加入服務。

public void ConfigureServices(IServiceCollection services)
{
    services.AddResponseCaching();

    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}

 

我們使用Home/About來測試ResponseCacheFilterAttribute

Duration可設定Cache的維持時間秒數(倒數計時方式),

我們將時間設為10秒。

[ResponseCache(Duration = 10)]
public IActionResult About(int? id)
{
    ViewData["lastTime"] = DateTime.Now;

    return View();
}

 

About.cshtml

@{
    ViewData["Title"] = "About";
}

<div class="alert alert-success">
    @ViewData["lastTime"]
</div>

 

好了之後來進行測試。

 

接著點選上方About的連結,

因為有設定ResponseCache,

所以會顯示一樣的時間,

但超過10秒時間就會更新。

 

一樣的行為我們使用F5來進行測試,

會發現得到的時間會一直更新

這段也是讓我疑惑了一下,

感謝StackOverFlow文章幫忙解惑,

 

摘述如下,如果有講錯請幫忙補充:

F5因為本身意圖就是要「重新整理」,所以預設並不會使用Response-Cache中的Content,

 

按下F5後比較Request跟Response Headers的差異,

可以看到Response雖然max-age=10,

但Request中直接設定max-age=0。

 


ResponseCache Middleware

MiddlewareASP.Net Core中另一種ReponseCache的使用方式,

我們可以在StartupConfigure中設定。

使用形式如下:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{

    app.Use(async (context, next) =>
    {
        context.Response.GetTypedHeaders().CacheControl =
            new Microsoft.Net.Http.Headers.CacheControlHeaderValue()
            {
                Public = true,
                MaxAge = TimeSpan.FromSeconds(10),
            };
        context.Response.Headers[Microsoft.Net.Http.Headers.HeaderNames.Vary] =
            new string[] { "Accept-Encoding" };
        await next();
    });

    app.UseMvc(routes =>
    {
        routes.MapRoute(
            name: "default",
            template: "{controller=Home}/{action=Index}/{id?}");
    });
}

Microsoft.Net.Http.Headers.CacheControlHeaderValue中,

提供了許多ResponseCache中會設定到的參數(如下圖),


如果有需要細部客製調整的部份,

建議使用自訂的ResponseCacheMiddleware搭配ExtensionMethod使用。

另外官方也有介紹ResponseCacheMiddleware時常用的Header,
有興趣的讀者可以參考[此連結](https://docs.microsoft.com/zh-tw/aspnet/core/performance/caching/middleware?view=aspnetcore-2.1#http-headers-used-by-response-caching-middleware)。

Response Cache Condition

Response Cache使用上其實有很多條件限制,

不注意的話很可能在裡面繞了一大圈找不到方向,

以下限制條件摘錄自MSDN

  • Response回應的HttpStatusCode必須200
  • 請求方法必須符合GetHead(Head=沒有Body的Get)。
  • Header中不能含有AuthorizationSet-Cookie。
  • Header中Vary不能設定為*
  • Header中Cache-Control只能是public
  • 回傳結果在進入此層之前不能被修改(意思是Middleware順序比ResponseCache Middleware前面的不能修改Response的回傳結果)
  • 回傳的Content大小不能超過MaximumBodySize
  • Response Cache的總大小不能超過SizeLimit
  • 不能設定成no-storeno-cache
  • 不能使用IHttpSendFileFeature(非同步檔案傳輸跟Response Cache的使用情境衝突)

 

Reponse Cache的部分就簡介到這邊,

如有錯誤資訊再麻煩指正。

 

參考

https://docs.microsoft.com/zh-tw/aspnet/core/performance/caching/response?view=aspnetcore-2.1

http://www.talkingdotnet.com/response-caching-in-asp-net-core-1-1/