有时,您可能希望缓存某页,但是会基于请求为该页创建不同的版本。例如,根据查询字符串中传递的值,该页可能具有不同的输出。
ASP.NET 允许在输出缓存中缓存同一页的多个版本。输出缓存可能会因下列因素而异:
-
初始请求 (HTTP GET) 中的查询字符串。
-
回发时传递的控制值(HTTP POST 值)。
-
随请求传递的 HTTP 标头。
-
发出请求的浏览器的主版本号。
-
该页中的自定义字符串。在这种情况下,可以在 Global.asax 文件中创建自定义代码以指定该页的缓存行为。
可以通过以下两种方法来缓存页输出的多个版本:使用 @ OutputCache 指令的属性以声明方式,或者使用 HttpCachePolicy 类的属性和方法以编程方式。
@ OutputCache 指令包括四个可用来缓存页输出的多个版本的属性:
-
VaryByParam 属性可用来使缓存输出因查询字符串而异。
获取查询字符串或窗体 POST 参数的逗号分隔列表,该列表由输出缓存用来改变缓存项。
如果该属性设置为多个参数,则对于每个指定的参数,输出缓存都包含请求的文档的不同版本。可能的值包括“none”、“*”以及任何有效的查询字符串或 POST 参数名。
注意 在用于缓存目的时,ASP.NET 将带相同键/值对的查询字符串值或窗体发送值视为相同,无论参数传递的顺序如何。然而,对于缓存目的,参数名是区分大小写的,ASP.NET 将为大写和小写的参数名和参数值缓存不同版本的页。
使用参数以声明方式缓存页输出的多个版本
-
在 ASP.NET 页中包括 @ OutputCache 指令,该指令带有 Duration 属性。Duration 属性是必需的,并且必须将其设置为大于零的整数。
-
在 @ OutputCache 指令中,包括 VaryByParam 属性,并将其值设置为想要使页随之变化的查询字符串或窗体发送参数的名称。
下面的代码示例将页缓存 60 秒,并指定将要根据 City 查询字符串值或窗体发送参数缓存页输出的不同版本。
<%@ OutputCache Duration="60" VaryByParam="City" %>
注意 如果要根据多个参数改变输出缓存,请包括以分号 (;) 作为分隔符的参数名称的列表。如果要根据所有的参数值来改变缓存,请将 VaryByParam 属性设置为星号 (*)。下面的代码示例演示如何通过 City 和 ZipCode 参数改变页输出。
使用参数以编程方式缓存页输出的多个版本
-
在页的 Page_Load 事件中,对 Response 对象的 Cache 属性调用 SetCacheability 和 SetExpires 方法。
-
将参数名指定为 Response 对象的 VaryByParams 属性的变量,并将该属性设置为 true。
下面的代码示例演示当具有不同的 Zip 参数值的请求到达服务器时,如何缓存页的多个版本。
Response.Cache.SetExpires(DateTime.Now.AddMinutes(1.0));
Response.Cache.SetCacheability(HttpCacheability.Public);
Response.Cache.SetValidUntilExpires(true);
Response.Cache.VaryByParams["Zip"] = true;
注意 如果要根据多个参数改变缓存的内容,请多次设置 VaryByParams 属性。如果要根据所有标头值改变缓存的内容,请将 VaryByHeader 属性设置为星号 (*)。
-
-
VaryByControl 属性可用来使缓存输出因控制值而异。
获取或设置一组分号分隔的控件标识符,这些标识符包含在当前页或用户控件内,用于改变当前缓存项。
分号分隔的字符串列表,用于改变项的输出缓存。VaryByControl 属性设置为完全限定的控件标识符,其中标识符是控件 ID 的串联,从顶级父级控件开始并以美元符号 ($) 分隔。 -
VaryByHeader 属性可用来使缓存输出因请求的 HTTP 标头而异。
获取或设置用于改变缓存项的一组逗号分隔的标头名称。标头名称标识与请求关联的 HTTP 标头。
如果该属性设置为多个标头,则对于每个指定的标头,输出缓存都包含请求的文档的不同版本。
根据 HTTP 标头值以声明方式对某页的各个版本进行缓存
-
在 ASP.NET 页中,在 @ OutputCache 指令中包括必需的 Duration 和 VaryByParam 或 VaryByControl 属性。必须将 Duration 属性设置为大于零的整数。如果希望只按 HTTP 标头值进行缓存,则必须将 VaryByParam 属性设置为“None”。
-
在 @ OutputCache 指令中,包含 VaryByHeader 属性,将其值设置为要作为改变缓存内容的依据的 HTTP 标头的名称。
下面的示例将页缓存 60 秒,并根据随 Accept-Language HTTP 标头传递的值设置要缓存的页的版本:
<%@ OutputCache Duration="60" VaryByParam="None" VaryByHeader="Accept-Language" %>
注意 如果要根据多个标头改变缓存的内容,请以分号 (;) 作为分隔符包括标头名称的列表。如果要根据所有标头值改变缓存的内容,请将 VaryByHeader 属性设置为星号 (*)。
根据 HTTP 标头值以编程方式对某页的各个版本进行缓存
-
在页的 Page_Load 方法中,对页的 Response 对象的 Cache 属性调用 SetCacheability 和 SetExpires 方法。
-
将 VaryByHeaders 属性中的 HTTP 标头值设置为 true。
下面的代码示例演示如何为有不同的 Accept-Language HTTP 标头值的请求,将某页的多个版本缓存一分钟之久。
protected void Page_Load(object sender, EventArgs e)
{
Response.Cache.SetExpires(DateTime.Now.AddMinutes(1d));
Response.Cache.SetCacheability(HttpCacheability.Public);
Response.Cache.SetValidUntilExpires(true);
}
注意 如果要根据多个标头改变缓存的内容,需要在 VaryByHeaders 属性中设置多个值。如果要根据所有标头改变缓存的内容,请将 VaryByHeaders["VaryByUnspecifiedParameters"] 设置为 true。
-
-
VaryByCustom 属性可用来使缓存输出因浏览器类型或您定义的自定义字符串而异。
获取输出缓存用来改变缓存项的自定义字符串列表。如果将该属性指定为“browser”,则缓存项将随浏览器类型和主版本号变化。如果输入了自定义字符串,则必须在应用程序的 Global.asax 文件中重写 HttpApplication.GetVaryByCustomString 方法。
注意 主版本和浏览器类型信息是通过 HttpBrowserCapabilities 对象的 MajorVersion 属性在当前请求中传递的。有关更多信息,请参见如何:在 ASP.NET 网页中检测浏览器类型。
基于浏览器类型以声明方式缓存页的多个版本
-
在 ASP.NET 页中,包括一个具有必需的 Duration 以及 VaryByParam 或 VaryByControl 属性的 @ OutputCache 指令。必须将 Duration 属性设置为大于零的整数。如果希望仅按浏览器类型进行缓存,请将 VaryByParam 属性设置为“None”。
-
在 @ OutputCache 指令中,包括 VaryByCustom 属性并将其设置为“browser”。
下面的示例将导致持续缓存该页达 10 秒。输出将因浏览器类型而异。
<%@ OutputCache Duration="10" VaryByParam="None" VaryByCustom="browser" %>
基于浏览器类型以编程方式缓存页的多个版本。
-
在页代码中,对页的 Response 属性的 Cache 属性调用 SetExpires 和 SetCacheability 方法。
-
调用 SetVaryByCustom 方法,在 custom 参数中传递值“browser”。
下面的代码示例演示如何持续缓存页的多个版本达 1 分钟。输出将因发出请求的浏览器的类型而异。
protected void Page_Load(object sender, EventArgs e)
{
Response.Cache.SetExpires(DateTime.Now.AddMinutes(1d));
Response.Cache.SetCacheability(HttpCacheability.Public);
Response.Cache.SetValidUntilExpires(true);
Response.Cache.SetVaryByCustom("browser");
}
除了按浏览器类型和参数进行不同的输出缓存行为外,还可以根据您定义的方法所返回的不同字符串对页输出的多个版本进行缓存。
根据自定义字符串对页进行缓存时,应首先指定要使用的自定义字符串的标识符。然后在应用程序的 Global.asax 文件中创建一个方法,该方法接受此标识符,并且返回一个值,作为进行不同的输出缓存行为的依据。
根据自定义字符串对页输出的多个版本进行缓存
-
在 ASP.NET 页中包括 @ OutputCache 指令,该指令带有必需的 Duration 和 VaryByParam 属性。必须将 Duration 属性设置为大于零的整数。如果不想使用 VaryByParam 属性提供的功能,则必须将其值设置为“无”。
-
若要以声明方式设置自定义字符串,请在 @ OutputCache 指令中包括 VaryByCustom 属性,并将该属性设置为您要作为进行不同输出缓存行为的依据的字符串。
下面的指令根据自定义字符串“minorversion”改变页输出。
<%@ OutputCache Duration="10" VaryByParam="None" VaryByCustom="minorversion" %>
-
若要以编程方式设置自定义字符串,请调用 SetVaryByCustom 方法,并将要使用的自定义字符串传递给它。
下面的代码示例演示如何将自定义字符串设置为“minorversion”。
C#Response.Cache.SetVaryByCustom("minorversion");
注意 如果试图以编程方式和声明方式设置自定义字符串,则会收到 InvalidOperationException。您需要选择其中一种方法。
被重写的方法接受您在 VaryByCustom 属性或 SetVaryByCustom 方法中设置的字符串,作为它的 arg 参数。例如,有些页可能根据请求浏览器的次版本进行缓存。对于这些页,可以将 VaryByCustom 属性设置为“minorversion”。然后,在被重写的 GetVaryByCustomString 方法中,可以检查 arg 参数,并根据 arg 参数的值是否为“minorversion”返回不同的字符串。
下面的代码示例演示一个 Global.asax 文件,其中的 GetVaryByCustomString 方法被重写。
C#<%@ Application language="C#" %> <script runat="server"> public override string GetVaryByCustomString(HttpContext context, string arg) { if(arg == "minorversion") { return "Version=" + context.Request.Browser.MinorVersion.ToString(); } return base.GetVaryByCustomString(context, arg); } </script>
-
-
-
注意 您必须在任何 @ OutputCache 指令中包括 VaryByParam 属性或 VaryByControl 属性。但是,如果您不需要使缓存输出因控制值或参数而异,则可以定义值为 None 的 VaryByParam。
HttpCachePolicy 类提供两个属性和一个方法,您可以通过它们以编程方式指定与以声明方式所能设置的缓存配置相同的缓存配置。使用 VaryByParams 和 VaryByHeaders 属性可以分别指定查询字符串参数和标头名称作为缓存策略改变依据。使用 SetVaryByCustom 方法可以定义要作为输出缓存改变依据的自定义字符串。