將動態內容新增至快取的頁面 (C#)

Microsoft提供

瞭解如何在相同的頁面中混合動態和快取的內容。 快取後替代可讓您在已快取輸出的頁面內顯示動態內容,例如橫幅廣告或新聞專案。

藉由利用輸出快取,您可以大幅改善 ASP.NET MVC 應用程式的效能。 每次要求頁面時,都可以產生頁面一次,並在記憶體中快取多個使用者。

但發生問題。 如果您需要在頁面中顯示動態內容,該怎麼辦? 例如,假設您想要在頁面中顯示橫幅廣告。 您不希望快取橫幅廣告,讓每位使用者看到完全相同的廣告。 您不會以這種方式獲利!

幸運的是,有一個簡單的解決方案。 您可以利用稱為快取 後替代ASP.NET 架構的功能。 快取後替代可讓您在記憶體中快取的頁面中替代動態內容。

一般而言,當您使用 [OutputCache] 屬性輸出快取頁面時,頁面會在伺服器和用戶端上快取, (網頁瀏覽器) 。 當您使用快取後替代時,只會在伺服器上快取頁面。

使用快取後替代

使用快取後替代需要兩個步驟。 首先,您需要定義方法,這個方法會傳回字串,代表您想要在快取頁面中顯示的動態內容。 接下來,您會呼叫 HttpResponse.WriteSubstitution () 方法,將動態內容插入頁面。

例如,假設您想要在快取的頁面中隨機顯示不同的新聞專案。 List 1 中的 類別會公開名為 RenderNews () 的單一方法,它會從三個新聞專案清單中隨機傳回一個新聞專案。

清單 1 – Models\News.cs

using System;
using System.Collections.Generic;
using System.Web;

namespace MvcApplication1.Models
{
    public class News
    {
        public static string RenderNews(HttpContext context)
        {
            var news = new List<string> 
                { 
                    "Gas prices go up!", 
                    "Life discovered on Mars!", 
                    "Moon disappears!" 
                };
            
            var rnd = new Random();
            return news[rnd.Next(news.Count)];
        }
    }
}

若要利用快取後替代,您可以呼叫 HttpResponse.WriteSubstitution () 方法。 WriteSubstitution () 方法會設定程式碼,以動態內容取代快取頁面的區域。 WriteSubstitution () 方法可用來在清單 2 的檢視中顯示隨機新聞專案。

清單 2 – Views\Home\Index.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Index.aspx.cs" Inherits="MvcApplication1.Views.Home.Index" %>
<%@ Import Namespace="MvcApplication1.Models" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>Index</title>
</head>
<body>
    <div>

    <% Response.WriteSubstitution(News.RenderNews); %>
        
    <hr />
    
    The content of this page is output cached.
    <%= DateTime.Now %>

    </div>
</body>
</html>

RenderNews 方法會傳遞至 WriteSubstitution () 方法。 請注意,未呼叫 RenderNews 方法, (沒有括弧) 。 相反地,方法的參考會傳遞至 WriteSubstitution () 。

索引檢視已快取。 檢視是由清單 3 中的控制器所傳回。 請注意,Index () 巨集指令是以 [OutputCache] 屬性裝飾,導致索引檢視快取 60 秒。

清單 3 – Controllers\HomeController.cs

using System.Web.Mvc;

namespace MvcApplication1.Controllers
{
    [HandleError]
    public class HomeController : Controller
    {
        [OutputCache(Duration=60, VaryByParam="none")]
        public ActionResult Index()
        {
            return View();
        }
    }
}

即使快取 [索引] 檢視,當您要求 [索引] 頁面時,也會顯示不同的隨機新聞專案。 當您要求 [索引] 頁面時,頁面顯示的時間不會變更 60 秒, (請參閱圖 1) 。 時間不會變更的事實會證明頁面已快取。 不過,WriteSubstitution () 方法插入的內容 – 隨機新聞專案 - 會隨著每個要求而變更。

圖 1 – 在快取頁面中插入動態新聞專案

clip_image002

在協助程式方法中使用快取後替代

利用快取後替代的較簡單方式,是在自訂協助程式方法中封裝 WriteSubstitution () 方法的呼叫。 此方法是由清單 4 中的協助程式方法所說明。

清單 4 – AdHelper.cs

using System;
using System.Collections.Generic;
using System.Web;
using System.Web.Mvc;

namespace MvcApplication1.Helpers
{
    public static class AdHelper
    {
        public static void RenderBanner(this HtmlHelper helper)
        {
            var context = helper.ViewContext.HttpContext;
            context.Response.WriteSubstitution(RenderBannerInternal);
        }
        
        private static string RenderBannerInternal(HttpContext context)
        {
            var ads = new List<string> 
                { 
                    "/ads/banner1.gif", 
                    "/ads/banner2.gif", 
                    "/ads/banner3.gif" 
                };

            var rnd = new Random();
            var ad = ads[rnd.Next(ads.Count)];
            return String.Format("<img src='{0}' />", ad);
        }
    }
}

清單 4 包含公開兩種方法的靜態類別:RenderBanner () 和 RenderBannerInternal () 。 RenderBanner () 方法代表實際的協助程式方法。 這個方法會擴充標準 ASP.NET MVC HtmlHelper 類別,讓您可以在檢視中呼叫 Html.RenderBanner () ,就像任何其他協助程式方法一樣。

RenderBanner () 方法會呼叫 HttpResponse.WriteSubstitution () 方法,並將 RenderBannerInternal () 方法傳遞至 WriteSubstitution () 方法。

RenderBannerInternal () 方法是私用方法。 這個方法不會公開為協助程式方法。 RenderBannerInternal () 方法會從三個橫幅廣告影像清單中隨機傳回一個橫幅廣告影像。

清單 5 中修改過的索引檢視說明如何使用 RenderBanner () 協助程式方法。 請注意,檢視頂端包含額外的 < %@ Import % > 指示詞,以匯入 MvcApplication1.Helpers 命名空間。 如果您忽略匯入此命名空間,則 RenderBanner () 方法將不會顯示為 Html 屬性上的方法。

清單 5 – Views\Home\Index.aspx (with RenderBanner () 方法)

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Index.aspx.cs" Inherits="MvcApplication1.Views.Home.Index" %>
<%@ Import Namespace="MvcApplication1.Models" %>
<%@ Import Namespace="MvcApplication1.Helpers" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>Index</title>
</head>
<body>
    <div>

    <% Response.WriteSubstitution(News.RenderNews); %>
    
    <hr />
    
    <% Html.RenderBanner(); %>
    
    <hr />
    
    The content of this page is output cached.
    <%= DateTime.Now %>

    </div>
</body>
</html>

當您要求清單 5 中檢視呈現的頁面時,每個要求都會顯示不同的橫幅廣告, (請參閱圖 2) 。 頁面已快取,但橫幅廣告會由 RenderBanner () 協助程式方法動態插入。

圖 2 – 顯示隨機橫幅廣告的索引檢視

clip_image004

總結

本教學課程說明如何在快取頁面中動態更新內容。 您已瞭解如何使用 HttpResponse.WriteSubstitution () 方法來讓動態內容插入快取的頁面。 您也瞭解如何在 HTML 協助程式方法中封裝 WriteSubstitution () 方法的呼叫。

盡可能利用快取 , 可能會對 Web 應用程式的效能產生重大影響。 如本教學課程所述,即使您需要在頁面中顯示動態內容,您也可以利用快取。