首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> ASP.NET 基礎 >> ASP.NET 基礎

ASP.NET OutputCache 快取鍵生成機制深度解析:CreateOutputCachedItemKey 內部邏輯

     編輯:ASP.NET 基礎

前言

ASP.NET OutputCache 模組透過 OutputCacheModule 在管線中掛載 ResolveRequestCache(讀取快取)與 UpdateRequestCache(寫入快取)事件。快取分為兩層:快取策略(CachedVary)與 快取資料(CachedRawResponse)。一個策略可對應多筆資料(如依查詢字串、Header 區分)。核心在於 CreateOutputCachedItemKey 如何依據請求特徵生成唯一鍵值。

鍵值生成流程概覽

方法簽名:CreateOutputCachedItemKey(HttpContext context, CachedVary cachedVary)

  • 策略鍵:cachedVary = null → 僅含 HTTP 動詞 + 路徑。
  • 資料鍵:cachedVary != null → 依策略設定追加 VaryByHeader、QueryString、Form、Custom、ContentEncoding 等維度。

基礎前綴:HTTP 動詞與路徑

StringBuilder builder;
if (verb == HttpVerb.POST) 
    builder = new StringBuilder("a1", path.Length + 2);
else 
    builder = new StringBuilder("a2", path.Length + 2);

builder.Append(CultureInfo.InvariantCulture.TextInfo.ToLower(path));
// 例:GET /Home/Index → "a2/home/index"

策略維度迴圈(H、Q、F 三階段)

對 i = 0..2 執行,分別處理:

階段標記來源條件
0HcachedVary._headers (VaryByHeader)ServerVariables
1QcachedVary._params (VaryByParam)QueryString + _varyByAllParams
2FcachedVary._params (VaryByParam)POST 且 Form + _varyByAllParams

每階段邏輯:

  1. 附加標記字元(H/Q/F)。
  2. 取得對應的鍵名陣列 array 與值集合 serverVarsWithoutDemand。
  3. 若 _varyByAllParams == true(即 VaryByParam="*"),則取該集合所有鍵,轉小寫、排序。
  4. 逐一追加格式:N{key}V{value},值為 null 時用 +n+ 代替。

後續固定段落

  • C:固定分隔符。
  • VaryByCustom:若設定,追加 N{customKey}V{customValue},值由 GetVaryByCustomString 取得,異常則用 +e+。
  • D:POST 非表單且 _varyByAllParams 時,將 Request Body 雜湊 (Base64) 附加。
  • E:ContentEncoding,若回應編碼在 _contentEncodings 清單中則附加編碼名稱。

關鍵屬性來源對照表

實務啟示

  1. 鍵值爆炸風險:濫用 VaryByParam="*" 或大量 Header 會導致快取碎片化,嚴重浪費記憶體。
  2. 自訂 VaryByCustom:可實作 GetVaryByCustomString 依使用者角色、裝置類型等切分快取。
  3. 除錯技巧:可透過反射或自訂 OutputCacheProvider 記錄實際生成的鍵值,驗證快取命中率。
理解 CreateOutputCachedItemKey 邏輯,是精準控制 OutputCache 行為、避免「以為快取了其實沒命中」的關鍵。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
CachedVary 屬性對應 OutputCache 設定影響鍵值條件
_headersVaryByHeaderHeader 名稱/值不同 → 鍵不同
_paramsVaryByParam參數名稱/值不同 → 鍵不同
_varyByAllParamsVaryByParam="*"true 時所有 QueryString/Form 參數皆納入
_varyByCustomVaryByCustom自訂字串 + GetVaryByCustomString 回傳值
_contentEncodingsVaryByContentEncoding回應編碼符合清單 → 附加編碼名