八、缓存和会话——分布式、服务器和客户端

在本章中,我们将介绍:

  • 使用。net 缓存和 MemoryCache
  • 用缓存标签助手缓存 HTML
  • 使用 ResponseCache 属性
  • 使用会话
  • 使用 Redis 作为本地缓存
  • 在 Azure 上使用 Redis 作为缓存
  • 使用 HTML5 缓存清单进行缓存
  • 使用 HTML5 localStorage 和 sessionStorage 缓存

介绍

在本章中,我们将学习在应用开发中用于存储数据的不同机制。 我们将学习。net 中的服务器端特性,但不是 IIS,因为现在有了 ASP.NET Core,我们尝试不依赖于服务器,并使用中间件来设计应用。 这就是为什么我们不讨论我们已经知道的 IIS 缓存机制,例如输出缓存。

我们还将了解一些 HTML5 特性,以缓存文件或数据在客户端。 在 JavaScript 中,该数据可以是简单数据,也可以是复杂数据。 如果它很复杂,我们将它存储为 JSON。

为了存储这些数据,我们将使用名为localStoragesessionStorage的 JavaScript 全局变量。 为了缓存文件,我们倾向于使用清单文件。

最后,我们将学习如何使用 IndexedDB 在客户端机制中将数据存储为 NoSQL 数据(或非关系数据作为键-值对),或者在 Azure 上使用 Redis 的分布式缓存机制。

对于我们将在本章中讨论的客户端缓存特性,我们必须参考www.caniuse.com以确保我们使用的浏览器具有这些 HTML5 功能。 为了避免 JavaScript 错误(它可能会阻塞应用的其他客户端脚本),我们可以使用诸如Modernizr这样的库来允许我们以编程方式检查浏览器的 HTML5 功能。

使用。net 缓存和 MemoryCache

在这个食谱中,我们将学习如何在 ASP 中使用默认的 Cache 对象.NET Core 缓存 CLR 对象。

准备

我们将创建一个空的 ASP.NET Core web 应用运行在。NET Framework 和 VS 2017 上。

怎么做……

  1. 首先,我们导入以下依赖项,以便能够在 ASP 中使用缓存.NET Core 应用:
"Microsoft.Extensions.Caching.Memory": "2.0.0"  
  1. 接下来,我们导入 MVC 依赖项:
"Microsoft.AspNetCore.Mvc": "2.0.0"  
  1. 我们现在可以添加缓存中间件:
public void ConfigureServices(IServiceCollection services) 
{ 
    services.AddMemoryCache(); 
    services.AddMvc(); 
} 
public void Configure(IApplicationBuilder app) 
{ 
    app.UseMvc(routes => 
    { 
        routes.MapRoute( 
        name: "default", 
        template: "{controller=Home}/{action=Index}/{id?}"); 
    }); 
} 
  1. 接下来,我们在项目根目录下创建两个文件夹ControllersViews
  2. 然后通过右键单击Controllers目录并选择 Add | New item | MVC Controller 类来创建HomeController.cs
  3. 接下来,我们在控制器的构造函数中注入 IMemoryCache 接口:
public class HomeController : Controller 
{ 
    private readonly IMemoryCache cache; 
    public HomeController(IMemoryCache cache) 
    { 
        this.cache = cache;   
    } 
    ... 
} 
  1. 现在让我们添加一些数据到缓存:
public IActionResult Index() 
{ 
    var strToCache = "Hello from cache"; 
    DateTime absoluteExpiration = DateTime.Now.AddDays(1); 
    DateTimeOffset expirationFromNow = DateTime.UtcNow.AddDays(1); 

    cache.Set<string>("str1", strToCache); 
    cache.Set<string>("str1", strToCache, absoluteExpiration); 
    cache.Set<string>("str1", strToCache, expirationFromNow); 

    List<string> listColors = new List<string> 
    { 
        "green", "white", "black" 
    }; 
    cache.Set<List<string>>("listColors", listColors); 

    return View(); 
} 

我们必须设置键、值和可选的到期日期。

注意,使用下面的语法,我们不需要将对象强制转换到缓存中,也不需要从缓存中检索对象:

cache.Set<string>
cache.Set<List<string>>
  1. 接下来,我们将从缓存中检索一些数据。 要做到这一点,我们有几个选择:
cache.Get
cache.TryGetValue
cache.GetOrCreate
cache.GetOrCreateAsync 
public IActionResult TryShowCachedData() 
{ 
    var str1 = cache.Get<string>("str1"); 

    List<string> listColors = cache.Get<List<string>>("listColors"); 

    List<string> listStrings = null; 
    bool dataExist = cache.TryGetValue<List<string>>("lstStr", out listStrings); 
    if (!dataExist) 
        listStrings = new List<string>(); 
        return View(listStrings); 
} 

用缓存标签助手缓存 HTML

在本食谱中,我们将学习如何使用缓存标签助手。

准备

TagHelpers 允许开发者在 CSHTML 文件中使用他们的 c#类和方法。 使用 TagHelpers,开发者可以在 CSHTML 文件中重用大部分 c#代码和逻辑。

现在,我们将创建一个视图,在这个视图中,我们将使用 Cache TagHelper 来缓存视图中的元素。

怎么做……

  1. 首先,我们使用 TagHelperexpires-after:
<!-- expires-after -->  
<cache expires-after="@TimeSpan.FromMinutes(10)">
    @Html.Partial("_MyPartialView")
</cache>
  1. 接下来,我们使用 TagHelperexpires-on:
      <!-- expires-on -->  
      <cache expires-on="@DateTime.Today.AddDays(1).AddTicks(-1)">
         @Html.Partial("_MyPartialView")
      </cache>
  1. 接下来,我们使用 TagHelperexpires-sliding:
      <!-- expires-sliding -->  
      <cache expires-sliding="@TimeSpan.FromMinutes(5)">
         @Html.Partial("_MyPartialView")
      </cache>
  1. 接下来,我们使用 TagHelpervary-by-user:
      <!-- vary-by-query -->  
      <cache vary-by-user="true">
          @Html.Partial("_MyPartialView")
      </cache>
  1. 接下来,我们使用 TagHelpervary-by-route:
      <!-- vary-by-user -->  
      <cache vary-by-route="id">
          @Html.Partial("_MyPartialView")
      </cache>
  1. 接下来,我们使用 TagHelpervary-by-query:
      <!-- vary-by-route -->  
      <cache vary-by-query="search">
          @Html.Partial("_MyPartialView")
      </cache>
  1. 接下来,我们使用 TagHelpervary-by-header:
      <!-- vary-by-header -->  
      <cache vary-by-header="User-Agent">
          @Html.Partial("_MyPartialView")
      </cache>
  1. 接下来,我们使用 TagHelpervary-by-cookie:
      <!-- vary-by-cookie -->  
      <cache vary-by-cookie="MyAppCookie">
          @Html.Partial("_MyPartialView")
      </cache>
  1. 接下来,我们使用 TagHelpervary-by:
      <!-- vary-by -->  
      <cache vary-by="@ViewBag.ProductId">
          @Html.Partial("_MyPartialView")
      </cache>

它是如何工作的…

缓存可以显著提高应用的加载时间。 大多数情况下,我们缓存请求的输出,比如 HTML 和 Json。

Do not cache frequently-changed data, it's more problematic to invalidate cache before it's time-to-live duration.

TagHelper 基本上缓存内部块的输出。 缓存机制默认情况下,缓存内部块输出在单个实例中。

我们可以通过几个参数来增加实例计数,例如vary-by-headervary-by-cookie等等。

这些参数创建新的缓存实例为每个不同的键值对应的参数,如vary-by-query参数可以为创造新的缓存实例 q = aspnetcore,u = polatengin,水果=橙色查询串的 url。

另外,我们可以通过在cacheTagHelper 中添加一个到期策略来控制生存时间,例如expires-afterexpires-onexpires-sliding

参数确定缓存项在内存中的生存期。 稍后,缓存项将被自动删除。

expires-on参数确定缓存项在内存中的确切时间; 在此之后,缓存项将被自动删除。

参数确定缓存项在内存中的生存期。 它不同于expires-afterby,在缓存项上的每个读操作,都通过这个参数值滑动过期时间。 不读取过期时间将自动删除缓存项。

使用 ResponseCache 属性

在这个食谱中,我们将学习如何在 ASP 中使用ResponseCache属性.NET 的核心。

准备

我们将使用 VS 2017,并将创建一个控制器来操作ResponseCache属性。

怎么做……

  1. 首先,我们将Microsoft.AspNetCore.Mvc依赖添加到项目中:
      "dependencies": { 
    "Microsoft.AspNetCore.Mvc": "2.0.0", 
  1. 接下来,我们配置 ASP。 Startup.csConfigure方法中的 NET 路由:
      public void Configure(IApplicationBuilder app) 
       { 
            app.UseMvc(routes => 
            { 
                routes.MapRoute( 
                    name: "default", 
                    template: "{controller=Home}/{action=Index}/{id?}"); 
            }); 
} 
  1. 现在,我们配置Startup.cs来创建一些缓存配置文件,在ConfigureServices方法中添加一些代码:
      public void ConfigureServices(IServiceCollection services) 
       { 
            services.AddMvc(options => 
            { 
                options.CacheProfiles.Add("Default", 
                    new CacheProfile() 
                    { 
                        Duration = 60 
                    }); 
                options.CacheProfiles.Add("Never", 
                    new CacheProfile() 
                    { 
                        Location = ResponseCacheLocation.None, 
                        NoStore = true 
                    }); 
            }); 
} 
  1. 接下来,让我们创建一个控制器和一些视图。 我们将在 action 方法中添加缓存属性,为每个对应的视图参数化缓存选项:
      [ResponseCache(Duration = 30)] 
      public class HomeController : Controller 
      { 
         [ResponseCache(CacheProfileName = "Default")] 
         public IActionResult Index() 
         { 
             return View(); 
         } 

         [ResponseCache(CacheProfileName = " Never")] 
         public IActionResult NeverCachedView() 
         { 
             return View(); 
         } 

         [ResponseCache(Duration = 10, Location = 
                   ResponseCacheLocation.Any, NoStore = false)] 
         public IActionResult About() 
         { 
             ViewData["Message"] = 
                         "Your application description page."; 
             return View(); 
         } 

         [ResponseCache(Duration = 60, Location = 
                               ResponseCacheLocation.Client)] 
         public IActionResult Contact() 
         { 
             ViewData["Message"] = "Your contact page.";
             return View(); 
         } 
} 

它是如何工作的…

当我们使用 ReponseCache 属性时,当我们创建ResponseRequest时,我们生成 HTTP 报头及其值。 生成的 HTTP 头是Cache-ControlPragmaVary,它们的值取决于我们添加到 ResponseCache 属性的值。

ResponseCache 属性可以在控制器级别添加,也可以在动作方法级别添加。 在操作方法级别,ResponseCache 属性将覆盖装饰过的方法中的控制器属性。 目前,ResponseCache 不在服务器内存中缓存; 这个功能很快就会推出。

ResponseCache 属性如下:

  • 持续时间(以秒为单位)
  • 位置(任意、无或客户端)
  • NoStore(真或假)
  • VaryByHeader(头的名称)
  • CacheProfileName(在Startup.csConfigureServices方法中创建的配置文件)
  • 订单
For this decoration: 
[ResponseCache(CacheProfileName = "Default")] 
The generated header will be the following: 
Cache-Control: public,max-age=60 
For this decoration: 
[ResponseCache(CacheProfileName = " Never")] 
The generated headers will be the following: 
Cache-Control :"no-store,no-cache" 
Pragma :"no-cache" 

For this decoration: 
[ResponseCache(Duration = 10, Location =  
                  ResponseCacheLocation.Any, NoStore = false)] 
The generated header will be the following: 
Cache-Control :"public,max-age=10" 

For this decoration: 
[ResponseCache(Duration = 60, Location =  
                              ResponseCacheLocation.Client)] 
The generated header will be the following: 
Cache-Control :"private,max-age=60" 

使用会话

在本教程中,我们将学习如何在 ASP 中使用会话.NET 的核心。

准备

我们将使用 VS 2017,并创建一个控制器来操纵会话。

如何做它......

  1. 首先,我们将以下库添加到项目中:
      "Microsoft.AspNetCore.Session": "2.0.0" 
  1. 接下来,我们在Startup.cs中配置 Session。 我们还添加了 MVC 服务来使用 ASP.NET MVC 管道:
      public void ConfigureServices(IServiceCollection services) 
       { 
            services.AddSession(options => 
            { 
                options.IdleTimeout = TimeSpan.FromMinutes(30); 
                options.CookieName = ".Session"; 
            }); 

            services.AddMvc(); 
        } 

      public void Configure(IApplicationBuilder app) 
       { 
            app.UseSession(); 

            app.UseMvc(routes => 
            { 
                routes.MapRoute( 
                    name: "default", 
                    template: "{controller=Home}/{action=Index}/{id?}"); 
            }); 
        } 
  1. 接下来,我们创建一些 helper 方法来序列化对象,以便在 Session 中获取和存储对象:
      // Convert an object to a byte array 
        public byte[] ObjectToByteArray(Object obj) 
        { 
            BinaryFormatter bf = new BinaryFormatter(); 
            using (var ms = new MemoryStream()) 
            { 
                bf.Serialize(ms, obj); 
                return ms.ToArray(); 
            } 
        } 

        // Convert a byte array to an Object 
        public Object ByteArrayToObject(byte[] arrBytes) 
        { 
            using (var memStream = new MemoryStream()) 
            { 
                var binForm = new BinaryFormatter(); 
                memStream.Write(arrBytes, 0, arrBytes.Length); 
                memStream.Seek(0, SeekOrigin.Begin); 
                var obj = binForm.Deserialize(memStream); 
                return obj; 
            } 
        } 
  1. 接下来,让我们在HttpContext.Session对象中存储一个字符串列表:
      public IActionResult Index() 
       { 
            List<string> listColors = new List<string> 
            { 
                "green", "white", "black" 
            }; 
            var listColorsBytes = ObjectToByteArray(listColors); 
            HttpContext.Session.Set("listColors", listColorsBytes); 
            return View(); 
        } 
  1. 我们可以看到创建的 cookie 在浏览器中启动F12工具,之前在Startup.csConfigureServices方法中配置:

  1. 现在,我们从Session对象中检索这个字符串列表:
      public IActionResult Colors() 
       { 
            List<string> listColors = new List<string>(); 
            var listBytesColors = new Byte[1000];

            bool hasValue = 
             HttpContext.Session.TryGetValue("listColors", 
                                              out listBytesColors); 
            if(hasValue) 
                listColors = 
                   (List<string>)ByteArrayToObject(listBytesColors);

            return View(listColors); 
        } 
  1. 最后,让我们看看浏览器视图中的结果:

它是如何工作的…

使用HttpContext.Session对象,客户机在服务器的 RAM 中拥有相应的内存空间。 通过使用Session对象,我们可以开发能够在服务器中记住用户整个活动的应用。 例如,如果用户还没有登录,我们可以将用户重定向到登录页面; 成功登录后,应用可以记住登录用户的所有属性,并让用户在应用中导航。 我们可以清除Session对象,让应用忘记用户。 注销功能通常会清除Session对象。

使用 Redis 作为本地缓存

在这个食谱中,我们将学习如何在 Windows 上安装 Redis,并使用它作为一个缓存在内存系统与 ASP.NET Core MVC 应用。

准备

我们将下载 Windows 版的 Redis,并启动 VS 2017 来创建一个空的 web 应用。

怎么做……

  1. 首先让我们启动http://redis.io:

  1. 接下来,我们去下载| Windows 部分:

  1. 我们会自动重定向到一个名为 MSOpenTech/redis 的 GitHub 项目:

  1. 在以下 Windows 上的 Redis 部分,我们将找到一个 MSI 安装程序的链接:

  1. 这里是 MSI 的下载页面,但我们也可以下载 Linux 或 macOS 的二进制文件:

  1. 下载后,我们点击安装程序:

  1. 让我们选择 Redis 服务器的目标文件夹:

  1. 接下来,我们选择端口号,我们将请求 Redis 并添加一个例外到 Windows 防火墙:

  1. 接下来,我们添加内存限制:

  1. Redis 终于安装了:

  1. 现在我们将把 Redis 作为一个服务来运行。 要做到这一点,让我们通过在执行提示中输入services.msc来启动 Windows 上的服务控制台:

  1. 然后,我们右键单击 Redis 行,并选择运行,如果服务没有运行。 我们还将选择启动模式:

  1. 现在 Redis 安装好了,我们启动 vs2017 并创建一个空的 web 应用。
  2. 首先,我们必须在项目中导入StackExchange.Redis依赖来操作 Redis API:
    "StackExchange.Redis": "1.2.6" 
  1. 接下来,我们创建一些扩展方法来更有效地使用 Redis,因为我们必须序列化和反序列化clr对象,以二进制表存储在 Redis:
      using StackExchange.Redis; 
      using System.IO; 
      using System.Runtime.Serialization.Formatters.Binary; 

      public static class RedisCacheExtensions 
      { 

         public static T Get<T>(this IDatabase cache, string key) 
         { 
             return Deserialize<T>(cache.StringGet(key)); 
         } 

         public static void Set(this IDatabase cache, string key, 
                                                 object value) 
         { 
             cache.StringSet(key, Serialize(value)); 
         } 

         static byte[] Serialize(object o) 
         { 
             if (o == null) 
             { 
                   return null; 
             } 

             BinaryFormatter binaryFormatter = new BinaryFormatter(); 
             using (MemoryStream memoryStream = new MemoryStream()) 
             { 
                   binaryFormatter.Serialize(memoryStream, o); 
                   byte[] objectDataAsStream = memoryStream.ToArray(); 
                   return objectDataAsStream; 
             } 
         } 

         static T Deserialize<T>(byte[] stream) 
         { 
             if (stream == null) 
             { 
                   return default(T); 
             } 

             BinaryFormatter binaryFormatter = new BinaryFormatter(); 
             using (MemoryStream memoryStream = 
                                           new MemoryStream(stream)) 
             { 
                   T result = 
                         (T)binaryFormatter.Deserialize(memoryStream); 
                   return result; 
             } 
         } 
} 
  1. 接下来,我们创建一个ICacheRedis接口及其实现来封装 Redis 的配置和特性,并将这个实现注入到我们的 MVC 控制器中:
      public interface ICacheRedis 
      { 
         T Get<T>(string key); 
         void Set<T>(string key, T obj); 
      } 
      public class CacheRedis : ICacheRedis 
      { 
         private static IDatabase redis; 

         public T Get<T>(string key) 
         { 
             redis = Connection.GetDatabase(); 
             var obj = redis.Get<T>(key); 
             if (obj == null) 
                   return default(T); 

             return obj; 
         } 

         public void Set<T>(string key, T obj) 
         { 
             redis = Connection.GetDatabase(); 
             if (obj != null) 
                   redis.Set(key, obj); 
         } 

         public void InvalidateCache(string key) 
         { 
             IDatabase cache = Connection.GetDatabase(); 
             cache.KeyDelete(key); 
         } 

         private static Lazy<ConnectionMultiplexer> 
         lazyConnection = new Lazy<ConnectionMultiplexer>
         (() => 
         { 
             return ConnectionMultiplexer.Connect(
             "localhost:6379,abortConnect=False"); 
         }); 

         public static ConnectionMultiplexer Connection 
         { 
             get 
             { 
                   return lazyConnection.Value; 
             } 
         } 
     } 
  1. 然后我们在私有的lazyConnection字段中添加 Redis 本地连接字符串。
  2. 接下来,我们将Startup.cs配置为将ICacheRedis注入控制器:
      public void ConfigureServices(IServiceCollection services) 
       { 
   services.AddSingleton<ICacheRedis, CacheRedis>();
    ... 
} 
  1. 现在我们可以在控制器中注入并使用 Redis。 创建控制器后,让我们添加以下代码:
      public class HomeController : Controller 
      { 
         private ICacheRedis redisCache; 
         public HomeController(ICacheRedis redisCache) 
         { 
             this.redisCache = redisCache; 
         } 

         public IActionResult Index() 
         { 
             List<string> listColors = new List<string> 
             { 
                   "green", "white", "black" 

              redisCache.Set<List<string>>("listColors", listColors); 

             return View(); 
         } 

         public IActionResult ShowCacheData() 
         { 
             List<string> listColors = 
                      redisCache.Get<List<string>>("listColors"); 

             return View(listColors); 
         } 
} 
  1. 然后我们创建一个index方法,将数据存储在 Redis 上,以及一个ShowCacheData方法,从 Redis 缓存中检索和显示这些数据。
  2. 最后,我们可以看到 ShowCacheData 视图显示的结果:

它是如何工作的…

Redis 是一个非常高性能的内存对象存储与可配置的缓存过期策略。

很多网络应用都严重依赖 Redis,比如 Twitter, StackOverflow, GitHub, Pinterest, Snapchat 等等。

我们可以使用 Redis 以分布式的方式存储和检索内存中的数据。

在 Azure 上使用 Redis 作为缓存

在这个食谱中,我们将学习如何使用 Azure 上的 Redis 作为缓存在内存系统与 ASP.NET Core MVC 应用。

准备

首先,我们将连接到我们的 Azure 订阅,创建一个 Redis 缓存提供商,启动 VS 2017,并创建一个空的 web 应用。

怎么做……

  1. 首先,让我们启动http://portal.azure.com,连接我们的订阅,并选择 Redis 缓存:

  1. 然后我们将创建一个 Redis 缓存。 为此,我们配置它,添加一个 DNS 名称、一个订阅、一个资源组、一个位置和一个定价层:

  1. 刷新 Redis 缓存部分,我们可以看到新的 Redis 缓存刚刚创建:

  1. 现在 Redis 是在 Azure 上创建的,我们启动 VS 2017 并创建一个空的 web 应用。
  2. 首先,我们必须在项目中导入StackExchange.Redis依赖来操作 Redis API:
    "StackExchange.Redis": "1.2.6" 
  1. 接下来,我们创建一些扩展方法来更有效地使用 Redis,因为我们必须序列化和反序列化clr对象,以二进制表存储在 Redis:
      using StackExchange.Redis; 
      using System.IO; 
      using System.Runtime.Serialization.Formatters.Binary; 

      public static class RedisCacheExtensions 
      { 

         public static T Get<T>(this IDatabase cache, string key) 
         { 
             return Deserialize<T>(cache.StringGet(key)); 
         } 

         public static void Set(this IDatabase cache, string key, 
                                                 object value) 
         { 
             cache.StringSet(key, Serialize(value)); 
         } 

         static byte[] Serialize(object o) 
         { 
             if (o == null) 
             { 
                   return null; 
             } 

             BinaryFormatter binaryFormatter = new BinaryFormatter(); 
             using (MemoryStream memoryStream = new MemoryStream()) 
             { 
                   binaryFormatter.Serialize(memoryStream, o); 
                   byte[] objectDataAsStream = memoryStream.ToArray(); 
                   return objectDataAsStream; 
             } 
         } 

         static T Deserialize<T>(byte[] stream) 
         { 
             if (stream == null) 
             { 
                   return default(T); 
             } 

             BinaryFormatter binaryFormatter = new BinaryFormatter(); 
             using (MemoryStream memoryStream = 
                                           new MemoryStream(stream)) 
             { 
                   T result = 
                         (T)binaryFormatter.Deserialize(memoryStream); 
                   return result; 
             } 
         } 
} 
  1. 接下来,我们创建一个ICacheRedis接口及其实现来封装 Redis 的配置和特性,并将这个实现注入到我们的 MVC 控制器中:
      public interface ICacheRedis 
      { 
         T Get<T>(string key); 
         void Set<T>(string key, T obj); 
} 
      public class CacheRedis : ICacheRedis 
      { 
         private static IDatabase redis; 

         public T Get<T>(string key) 
         { 
             redis = Connection.GetDatabase(); 
             var obj = redis.Get<T>(key); 
             if (obj == null) 
                   return default(T); 

             return obj; 
         } 

         public void Set<T>(string key, T obj) 
         { 
             redis = Connection.GetDatabase(); 
             if (obj != null) 
                   redis.Set(key, obj); 
         } 

         public void InvalidateCache(string key) 
         { 
             IDatabase cache = Connection.GetDatabase(); 
             cache.KeyDelete(key); 
         } 

         private static Lazy<ConnectionMultiplexer> lazyConnection = 
                               new Lazy<ConnectionMultiplexer>(() => 
         { 
             return ConnectionMultiplexer.Connect(                                  "CookbookMvc6.redis.cache.windows.net:6380,
                password=IhwUE/oo4QNkBgEUpZ0AnM4pT81uL6/+mM5piGCJdGs=,
                ssl=True,abortConnect=False"); 
         }); 

         public static ConnectionMultiplexer Connection 
         { 
             get 
             { 
                   return lazyConnection.Value; 
             } 
         } 
} 
  1. 然后我们在私有的lazyConnection字段中添加 Redis 本地连接字符串。

ASP 的唯一区别是。 与前面的配方相比,NET 代码是连接字符串。

  1. 为了得到这个 Azure Redis 连接字符串,我们必须去我们的 Azure 门户,选择我们刚刚创建的 Redis 缓存,选择设置|访问键,并复制主连接字符串如下:

  1. 接下来,我们将Startup.cs配置为将ICacheRedis注入控制器:
      public void ConfigureServices(IServiceCollection services) 
       { 
   services.AddSingleton<ICacheRedis, CacheRedis>();
    ... 
} 
  1. 我们现在可以在控制器中注入和使用 Redis。 创建控制器后,让我们添加以下代码:
      public class HomeController : Controller 
      { 
         private ICacheRedis redisCache; 
         public HomeController(ICacheRedis redisCache) 
         { 
             this.redisCache = redisCache; 
         } 

         public IActionResult Index() 
         { 
             List<string> listColors = new List<string> 
             { 
                   "green", "white", "black" 

              redisCache.Set<List<string>>("listColors", listColors); 

             return View(); 
         } 

         public IActionResult ShowCacheData() 
         { 
             List<string> listColors = 
                      redisCache.Get<List<string>>("listColors"); 

             return View(listColors); 
         } 
} 
  1. 然后我们创建一个index方法,将数据存储在 Redis 上,以及一个ShowCacheData方法,从 Redis 缓存中检索和显示这些数据。

  2. 最后,我们可以看到 ShowCacheData 视图显示的结果:

使用 HTML5 缓存清单进行缓存

在本教程中,我们将学习如何使用 HTML5 清单文件,以便在缓存浏览器中存储 JavaScript 和 CSS 文件以及图像。

准备

要测试 HTML5 缓存清单文件,我们只需要创建一个空的 web 应用。 为了在应用的根目录中添加一个清单文件,将一些静态文件放入缓存和兼容 HTML5 的浏览器中。

怎么做……

我们将添加清单文件以在客户端启用缓存,并配置哪些文件将被缓存,哪些文件将不被缓存。

让我们从包含相对路径的 manifest 文件开始,如下所示:

<!DOCTYPE html> 
<html manifest="mySite.appcache"> 

或者用绝对路径:

<html manifest="http://www.mywebsite.com/mySite.appcache" 

首先,让我们分析一下缓存清单文件的结构:

CACHE MANIFEST 
# version 1.0 
  • 缓存:
/Content/Styles/Site.css 
/Content/Scripts/Site.js 
http://ajax.aspnetcdn.com/ajax/jQuery/jquery-2.2.0.js
  • 网络:
/Login/ 
Network.html 
  • 回退:
/Content/Images/Products/  

这里的CACHE MANIFEST部分仅用于添加注释(例如,关于版本)。

缓存清单的三个部分是cacheNETWORKFALLBACK:

  • CACHE:缓存的文件。 url 可以是相对的,也可以是绝对的。
  • NETWORK:不缓存的文件,必须来自网络。 url 可以是相对的,也可以是绝对的。
  • FALLBACK:如果浏览器不可用,浏览器应该使用的回退页面。

现在我们已经了解了如何手动创建清单文件,让我们通过使用首选任务运行器(gulpgrunt)来管理清单文件。

它是如何工作的……

HTML5 缓存清单是一个存储在应用根目录下的文件。 该文件描述了我们希望在浏览器缓存中的所有文件,以及它们的过期日期。

这是一种经常用于将资源缓存为localStorage的机制,以便更快地加载资源,减少服务器负载,并用于脱机应用。

W3C 建议我们使用.appcache 文件扩展名来创建一个缓存清单文件。

The HTML5 File API could be a good alternative to store images, videos, or text files, but it's only available on Firefox, Chrome, Safari, and Opera on Desktop.

使用 HTML5 localStorage 和 sessionStorage 缓存

在这个食谱中,我们将学习如何使用HTML5 存储 API(也叫网络存储,DOM 存储)localStoragesessionStorage对象,为了在客户端存储敏感数据。

准备

首先,我们用 VS 2017 创建一个空项目,并使用 JavaScript 代码存储数据。

我们对浏览器的最低要求是 IE8、Firefox 3.5 或 Chrome 4.0,这样才能从浏览器的 HTML5 功能中获益。

localStorageseesionStorage具有以下所有方法和属性:

  • getItem(key):存储键/值对
  • setItem(key, value):返回与键关联的值
  • removeItem(key):删除带有键的键/值对
  • clear():删除所有键/值对
  • length:返回已存储的 pair 个数

怎么做……

  1. 要测试localStoragesessionStorage在我们的浏览器上是否可用,我们可以使用以下代码:
(function() { 
   if (typeof sessionStorage != 'undefined') 
   // or 
   if (window['localStorage'] !== null) 
   // or using the ModernizR library 
   if (Modernizr.localstorage) 

})(); 
  1. 让我们用getItem(key)方法:
var color = localStorage.getItem('white'); 
var color = localStorage['white']; 
var color = localStorage.white; 
  1. 现在让我们使用setItem(key, value)方法在localStorage对象中存储数据:
localStorage.setItem('name', $('#name').val()); 
localStorage['name'] = $('#name').val(); 
localStorage.name = $('#name').val(); 
  1. 接下来,我们将在localStorage中存储一个复杂对象:
var colors = { white: '#000', black: '#fff' }; 
localStorage.setItem('htmlColors', JSON.stringify(colors)); 
  1. 要删除一个项目,让我们使用removeItem(key)方法:
localStorage.removeItem('lastName'); 
  1. 接下来,要清除localStorage对象,我们使用clear()方法:
localStorage.clear(); 
  1. 最后,要知道存储在localStorage对象中的项数,我们将使用length属性:
var storageCount = localStorage.length; 

它是如何工作的……

HTML5 存储对于提高应用的性能非常有用。 既然我们可以将这些数据存储在浏览器缓存对象中,为什么还要往返于 web 服务器呢?

HTML5 存储在所有现代浏览器中都可用,其容量限制为 5MB,但 Internet Explorer 支持 10MB 的限制。

localStoragesessionStorage是两个 JavaScript 对象存储键值对。 如果值是一个复杂的 JavaScript 对象,则必须使用JSON.stringify()将其存储为 JSON 字符串。

两者的区别是:

  • sessionStorage在导航会话期间共享同一选项卡或窗口中的数据
  • localStorage在所有选项卡和窗口之间共享数据,没有时间限制

If we work with old browsers, we can check programmatically with a library like ModernizR if the HTML Storage feature is available in the browser. ModernizR can do that for all HTML5 objects or APIs.

我们也可以使用持久存储将数据作为 cookie 存储在客户端上,但这种方式的容量有限; 我们只能在它上存储文本,并且它会被发送到服务器上的每个请求。 localStoragesessionStorage对象不能在不同的浏览器之间共享。

另请参阅

http://caniuse.com允许我们检查所有浏览器的 HTML5 API 可用性。