iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 25
0

前言

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

同步發表於個人點部落 - [鐵人賽Day25] ASP.Net Core MVC 進化之路 - 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後比較RequestResponse Headers的差異,
可以看到Response雖然max-age=10
Request中直接設定max-age=0

ConfigureServices中可以使用services.AddResponseCaching()調整ResponseCache使用設定。

  • SizeLimit : 調整Cache的記憶體空間限制(bytes)
  • MaximimBodySize : Request Body的最大bytes
  • UseCaseSensitivePaths : 是否忽略傳輸路由的大小寫
public void ConfigureServices(IServiceCollection services)
{
    services.AddResponseCaching(options =>
    {
        options.SizeLimit = 1024;
        options.MaximumBodySize = 1024 * 1024 * 100;
        options.UseCaseSensitivePaths = false;
    });

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

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,
有興趣的讀者可以參考此連結

Response Cache Condition

Response Cache使用上其實有很多條件限制,
不注意的話很可能在裡面繞了一大圈找不到方向,
以下摘錄自官方提供的限制條件

  • Response回應的HttpStatusCode為200
  • 請求方法必須符合GetHead(Head=沒有BodyGet)
  • 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/


上一篇
[鐵人賽Day24] - MemoryCache
下一篇
[鐵人賽Day26] - Response Compression(回應壓縮)
系列文
菜鳥練等區-ASP.Net Core MVC進化之路30

尚未有邦友留言

立即登入留言