MVC系統過濾器 OutputCacheAttribute

命名空間:  System.Web.Mvc
程序集:  System.Web.Mvc(在 System.Web.Mvc.dll 中)web

1、MVC緩存簡介

緩存是將信息(數據或頁面)放在內存中以免頻繁的數據庫存儲或執行整個頁面的生命週期,直到緩存的信息過時或依賴變動纔再次從數據庫中讀取數據或從新執行頁面的生命週期。在系統優化過程當中,緩存是比較廣泛的優化作法和見效比較快的作法。
MVC緩存本質上仍是.NET的一套緩存體系,只不過該緩存體系應用在了MVC框架上。下面的示例把緩存應用在MVC上。sql

緩存的經常使用場景:數據庫

數據被頻繁的使用,而且不多發生變化或對即時性的要求不高。api

2、Control緩存

Control緩存便是把緩存應用到整個Control上,該Control下的全部Action都會被緩存起來。Control緩存的粒度比較粗,應用也比較少些。瀏覽器

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

namespace MvcCache.Control.Controllers
{
    [OutputCache(Duration = 10)]
    public class ControlController : Controller
    {
        //
        // GET: /Home/
        public ActionResult Index()
        {
            ViewBag.CurrentTime = System.DateTime.Now;
            return View();
        }

        public ActionResult Index1()
        {
            ViewBag.CurrentTime = System.DateTime.Now;
            return View();
        }

    }
}

在名爲Control的Control中加入了OutputCache,並設置持續時間爲10秒(Duration=10),即每10秒後過時當再次觸發時更新緩存。下面是View中的代碼,打印ViewBag的時間。緩存

@{
    ViewBag.Title = "Index";
}

<h2>@ViewBag.CurrentTime</h2>

@{
    ViewBag.Title = "Index1";
}

<h2>@ViewBag.CurrentTime</h2>

3、Action緩存

即把緩存用到Action上,Action緩存爲比較經常使用的緩存方式,該方式粒度細一些。使用方法相似Control緩存。服務器

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

namespace MvcCache.Control.Controllers
{
    //Control不加緩存
    public class ActionController : Controller
    {
        //該Index的Action加緩存
        [OutputCache(Duration = 10)]
        public ActionResult Index()
        {
            ViewBag.CurrentTime = System.DateTime.Now;
            return View();
        }

        //該Action不加緩存
        public ActionResult Index1()
        {
            ViewBag.CurrentTime = System.DateTime.Now;
            return View();
        }

    }
}

Index加入了緩存,而Index1沒有加。此時Index1每次刷新頁面都會取到當前的時間並打印。mvc

@{
    ViewBag.Title = "Index";
 
}

<h2>@ViewBag.CurrentTime</h2>

@{
    ViewBag.Title = "Index1";
}

<h2>@ViewBag.CurrentTime</h2>

4、使用配置文件

當咱們須要將N個Control或Action加入緩存,而且緩存的參數是一致的狀況下,咱們能夠把相關的設置放到Web.config中,並在程序中加入相應的配置。app

<?xml version="1.0" encoding="utf-8"?>
<!--
  For more information on how to configure your ASP.NET application, please visit
  http://go.microsoft.com/fwlink/?LinkId=169433
  -->

<configuration>
  <appSettings>
    <add key="webpages:Version" value="2.0.0.0" />
    <add key="webpages:Enabled" value="false" />
    <add key="PreserveLoginUrl" value="true" />
    <add key="ClientValidationEnabled" value="true" />
    <add key="UnobtrusiveJavaScriptEnabled" value="true" />
  </appSettings>
  <system.web>
    <!--配置緩存-->
    <caching>
      <outputCacheSettings>
        <outputCacheProfiles>
          <add name="TestConfigCache" duration="10"/>
        </outputCacheProfiles>
      </outputCacheSettings>
    </caching>
    <!--配置緩存-->
    <httpRuntime targetFramework="4.5" />
    <compilation debug="true" targetFramework="4.5" />
    <pages>
      <namespaces>
        <add namespace="System.Web.Helpers" />
        <add namespace="System.Web.Mvc" />
        <add namespace="System.Web.Mvc.Ajax" />
        <add namespace="System.Web.Mvc.Html" />
        <add namespace="System.Web.Routing" />
        <add namespace="System.Web.WebPages" />
      </namespaces>
    </pages>
  </system.web>
  <system.webServer>
    <validation validateIntegratedModeConfiguration="false" />

    <handlers>
      <remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" />
      <remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
      <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
      <add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
      <add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
      <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
    </handlers>
  </system.webServer>

</configuration>

配置緩存節只須要將其放在system.web節下便可,下面是使用的方法框架

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

namespace MvcCache.Control.Controllers
{
    public class ConfigController : Controller
    {
        //TestConfigCache爲在配置文件中配置的緩存節
        [OutputCache(CacheProfile = "TestConfigCache")]
        public ActionResult Index()
        {
            ViewBag.CurrentTime = System.DateTime.Now;
            return View();
        }

    }
}

注:當Control與Action都應用了緩存時,以Action的緩存爲主。

5、OutputCache參數簡介

下面代碼爲mvc4的OutputCache的定義,因爲使用的是英文版本IDE和框架,所以註釋所有爲英文。後面的講解主要講解經常使用的屬性,對於緩存依賴這個重點內容在下面單獨講解使用方法。

若是想了解各個屬性的詳細說明及使用請查閱MSDN,連接地址以下:https://msdn.microsoft.com/zh-cn/library/system.web.mvc.outputcacheattribute.aspx

 using System;
using System.Web.UI;

namespace System.Web.Mvc
{
    // Summary:
    //     Represents an attribute that is used to mark an action method whose output
    //     will be cached.
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
    public class OutputCacheAttribute : ActionFilterAttribute, IExceptionFilter
    {
        // Summary:
        //     Initializes a new instance of the System.Web.Mvc.OutputCacheAttribute class.
        public OutputCacheAttribute();

        // Summary:
        //     Gets or sets the cache profile name.
        //
        // Returns:
        //     The cache profile name.
        public string CacheProfile { get; set; }
        //
        // Summary:
        //     Gets or sets the child action cache.
        //
        // Returns:
        //     The child action cache.
        public static System.Runtime.Caching.ObjectCache ChildActionCache { get; set; }
        //
        // Summary:
        //     Gets or sets the cache duration, in seconds.
        //
        // Returns:
        //     The cache duration.
        public int Duration { get; set; }
        //
        // Summary:
        //     Gets or sets the location.
        //
        // Returns:
        //     The location.
        public OutputCacheLocation Location { get; set; }
        //
        // Summary:
        //     Gets or sets a value that indicates whether to store the cache.
        //
        // Returns:
        //     true if the cache should be stored; otherwise, false.
        public bool NoStore { get; set; }
        //
        // Summary:
        //     Gets or sets the SQL dependency.
        //
        // Returns:
        //     The SQL dependency.
        public string SqlDependency { get; set; }
        //
        // Summary:
        //     Gets or sets the vary-by-content encoding.
        //
        // Returns:
        //     The vary-by-content encoding.
        public string VaryByContentEncoding { get; set; }
        //
        // Summary:
        //     Gets or sets the vary-by-custom value.
        //
        // Returns:
        //     The vary-by-custom value.
        public string VaryByCustom { get; set; }
        //
        // Summary:
        //     Gets or sets the vary-by-header value.
        //
        // Returns:
        //     The vary-by-header value.
        public string VaryByHeader { get; set; }
        //
        // Summary:
        //     Gets or sets the vary-by-param value.
        //
        // Returns:
        //     The vary-by-param value.
        public string VaryByParam { get; set; }

        // Summary:
        //     Returns a value that indicates whether a child action cache is active.
        //
        // Parameters:
        //   controllerContext:
        //     The controller context.
        //
        // Returns:
        //     true if the child action cache is active; otherwise, false.
        public static bool IsChildActionCacheActive(ControllerContext controllerContext);
        //
        // Summary:
        //     This method is an implementation of System.Web.Mvc.IActionFilter.OnActionExecuted(System.Web.Mvc.ActionExecutedContext)
        //     and supports the ASP.NET MVC infrastructure. It is not intended to be used
        //     directly from your code.
        //
        // Parameters:
        //   filterContext:
        //     The filter context.
        public override void OnActionExecuted(ActionExecutedContext filterContext);
        //
        // Summary:
        //     This method is an implementation of System.Web.Mvc.IActionFilter.OnActionExecuting(System.Web.Mvc.ActionExecutingContext)
        //     and supports the ASP.NET MVC infrastructure. It is not intended to be used
        //     directly from your code.
        //
        // Parameters:
        //   filterContext:
        //     The filter context.
        public override void OnActionExecuting(ActionExecutingContext filterContext);
        //
        // Summary:
        //     This method is an implementation of System.Web.Mvc.IExceptionFilter.OnException(System.Web.Mvc.ExceptionContext)
        //     and supports the ASP.NET MVC infrastructure. It is not intended to be used
        //     directly from your code.
        //
        // Parameters:
        //   filterContext:
        //     The filter context.
        public void OnException(ExceptionContext filterContext);
        //
        // Summary:
        //     This method is an implementation of System.Web.Mvc.IResultFilter.OnResultExecuted(System.Web.Mvc.ResultExecutedContext)
        //     and supports the ASP.NET MVC infrastructure. It is not intended to be used
        //     directly from your code.
        //
        // Parameters:
        //   filterContext:
        //     The filter context.
        public override void OnResultExecuted(ResultExecutedContext filterContext);
        //
        // Summary:
        //     Called before the action result executes.
        //
        // Parameters:
        //   filterContext:
        //     The filter context, which encapsulates information for using System.Web.Mvc.AuthorizeAttribute.
        //
        // Exceptions:
        //   System.ArgumentNullException:
        //     The filterContext parameter is null.
        public override void OnResultExecuting(ResultExecutingContext filterContext);
    }
}

經常使用屬性:
1)CacheProfile:緩存使用的配置文件的緩存名稱。

2)Duration:緩存時間,以秒爲單位,這個除非你的Location=None,能夠不添加此屬性,其他時候都是必須的。

3)OutputCacheLocation:枚舉類型,緩存的位置。當設置成None時,全部緩存將失效,默認爲Any。

    Any:頁面被緩存在瀏覽器、代理服務器端和web服務器端;

   Client:緩存在瀏覽器;

   DownStream:頁面被緩存在瀏覽器和任何的代理服務器端;

   Server:頁面被緩存在Web服務器端;

   None:頁面不緩存;

   ServerAndClient:頁面被緩存在瀏覽器和web服務器端;

4)VaryByParam:用於多個輸出緩存的字符串列表,並以分號進行分隔。默認時,該字符串與GET方法傳遞的參數或與POST方法傳遞的變 量相對應。當被設置爲多個參數時,輸出緩存將會爲每一個參數都準備一個與之相對應的文檔版本。可能值包括none,*,以及任何有效的查詢串或POST參數 名稱。

若是您不想要爲不一樣的已緩存內容指定參數,能夠將其設置爲none。若是想要指定全部的已緩存內容參數,能夠設置爲*。

6、緩存依賴

SqlDependency: 一個值,用於標識操做的輸出緩存所依賴的一組數據庫名稱和表名稱對。SqlCacheDependency 類在全部受支持的 SQL Server 版本 (7.0, 2000, 2005) 上監視特定的 SQL Server 數據庫表,數據庫表發生更改時,將自動刪除緩存項,並向 Cache 中添加新版本的項。

概 念理解起來很簡單,主要是如何應用。下面爲應用實例。示例說明:數據庫爲本地數據庫,庫名:wcfDemo(寫wcf教程時用的庫,懶了,直接用了),監 聽表名:user。緩存時間爲:3600秒即一小時。數據庫依賴週期爲500毫秒,即每0.5秒監聽下數據庫是否有變化,若是有變化則當即更新緩存。

第一步:創建Control,測試代碼以下:

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

namespace MvcCache.Control.Controllers
{
    public class SqlDependencyController : Controller
    {
        [OutputCache(CacheProfile = "SqlDependencyCache")]
        public ActionResult Index()
        {
            ViewBag.CurrentTime = System.DateTime.Now;
            return View();
        }

    }
}
<?xml version="1.0" encoding="utf-8"?>
<!--
  For more information on how to configure your ASP.NET application, please visit
  http://go.microsoft.com/fwlink/?LinkId=169433
  -->

<configuration>
  <!--數據庫鏈接字符串-->
  <connectionStrings>
    <add name="Conn" connectionString="server=localhost;database=wcfDemo;uid=sa;pwd=123456;" providerName="System.Data.SqlClient"/>
  </connectionStrings>
  <!--數據庫鏈接字符串-->
  <appSettings>
    <add key="webpages:Version" value="2.0.0.0" />
    <add key="webpages:Enabled" value="false" />
    <add key="PreserveLoginUrl" value="true" />
    <add key="ClientValidationEnabled" value="true" />
    <add key="UnobtrusiveJavaScriptEnabled" value="true" />
  </appSettings>
  <system.web>
    <!--配置緩存-->
    <caching>
      <sqlCacheDependency><!--緩存的數據庫依賴節-->
        <databases>
          <add name="UserCacheDependency" connectionStringName="Conn" pollTime="500"/><!--Conn:數據庫鏈接字符串的名稱,name隨便啓名,緩存節會用到-->
        </databases>
      </sqlCacheDependency>
      <outputCacheSettings>
        <outputCacheProfiles>
          <add name="SqlDependencyCache" duration="3600" sqlDependency="UserCacheDependency:user"/><!--UserCacheDependency:數據庫依賴配置節的名稱,user:數據庫中須要監聽的表名稱-->
        </outputCacheProfiles>
      </outputCacheSettings>
    </caching>
    <!--配置緩存-->
    <httpRuntime targetFramework="4.5" />
    <compilation debug="true" targetFramework="4.5" />
    <pages>
      <namespaces>
        <add namespace="System.Web.Helpers" />
        <add namespace="System.Web.Mvc" />
        <add namespace="System.Web.Mvc.Ajax" />
        <add namespace="System.Web.Mvc.Html" />
        <add namespace="System.Web.Routing" />
        <add namespace="System.Web.WebPages" />
      </namespaces>
    </pages>
  </system.web>
  <system.webServer>
    <validation validateIntegratedModeConfiguration="false" />

    <handlers>
      <remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" />
      <remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
      <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
      <add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
      <add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
      <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
    </handlers>
  </system.webServer>

</configuration>

注意:
1)因爲是緩存對數據庫的依賴,此外必須包含connectionStrings的節。

2)<add name="UserCacheDependency" connectionStringName="Conn" pollTime="500"/>

     connectionStringName:數據庫鏈接字符串的名稱

     pollTime:監聽數據庫變化的週期,以毫秒爲單位。即每500毫秒查看下數據庫是否有變化。

3)<add name="SqlDependencyCache" duration="3600" sqlDependency="UserCacheDependency:user"/>

      sqlDependency:數據依賴的節的名稱+冒號+數據表名稱(小寫)。若是這個依賴會用到多個表,則用分號間隔開,以下所示UserCacheDependency:user;UserCacheDependency:user1

第三步:啓用該數據庫表的緩存依賴通知功能

打開vs命令工具行,輸入:aspnet_regsql -S localhost -U sa -P 123456 -ed -d wcfDemo -et -t user

      -S localhost:數據庫地址

      -U sa:數據庫登陸名

      -P 123456:數據庫登陸密碼

      -d wcfDemo:數據庫的名稱

      -t user:表名稱(小寫)

 

由於只是監聽是否發生數據變化,所以表結構隨意,下面的個人表結構:

 

第四步:測試程序,上面的例子只打印了當前時間,若是不加入緩存依賴的狀況下,1小時以內都應該運行出的結果都是當前時間,每次Ctrl+F5強制 刷新瀏覽器時不發生任務變化。當加入緩存依賴後,只要對數據庫的數據進行任意修改都會更新緩存的時間,即更改數據後再刷新瀏覽器時會看到時間在變化

相關文章
相關標籤/搜索