首页 > 解决方案 > 如何将数据存储在缓存中?

问题描述

我创建了一个ViewComponent来显示一个List<Product>,列表是从REST API服务中获取的数据,这是我的类实现:

public class ProductsViewComponent : ViewComponent
{
    private readonly HttpClient _client;

    public ProductsViewComponent(HttpClient client)
    {
        _client = client ?? throw new ArgumentNullException(nameof(client));
    }

    public async Task<IViewComponentResult> InvokeAsync(string date)
    {
       using (var response = await _client.GetAsync($"/"product/get_products/{date}"))
       {
           response.EnsureSuccessStatusCode();
           var products = await response.Content.ReadAsAsync<List<Product>>();
           return View(products);
       }
    }
}

我将列表加载到文件夹中可用的 html 表中ComponentsViews\Shared\Components\Products\Default.cshtml.

在每个View需要显示Products我所做的事情中:

@await Component.InvokeAsync("Products", new { date = myDate })

使用如下配置REST API调用:HttpClientStartup.cs

services.AddHttpClient<ProductsViewComponent>(c =>
{
    c.BaseAddress = new Uri('https://api.myservice.com');
});

这很好用,但主要问题是每次用户重新加载页面或进入另一个需要显示产品列表的视图时,应用程序将再次API调用。

API是否可以将列表存储在缓存之类的东西中,如果日期等于选择的上一个日期,是否可以防止再次调用?

我正在学习ASP.NET Core,所以我不是这个论点的专家。

提前感谢您的帮助。

标签: c#asp.netasp.net-coreasp.net-core-mvc

解决方案


根据微软文档https://docs.microsoft.com/en-us/aspnet/core/performance/caching/memory?view=aspnetcore-2.1

你可以IMemoryCache用来缓存数据

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMemoryCache();

         services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
    }

    public void Configure(IApplicationBuilder app)
    {
        app.UseMvcWithDefaultRoute();
    }
}

并创建IMemoryCache. 这是 Microsoft 文档中的一个示例。您可以创建另一个类来一起处理这一切,在下面的示例中,这只是保存 DateTime 但是,您可以将任何对象保存在缓存中,当您尝试从缓存中读取该值时,只需将该对象转换为类型。

我强烈建议您阅读上述文档。

public class HomeController : Controller
{
    private IMemoryCache _cache;

    public HomeController(IMemoryCache memoryCache)
    {
        _cache = memoryCache;
    }

    public IActionResult CacheTryGetValueSet()
    {
       DateTime cacheEntry;

       // Look for cache key.
       if (!_cache.TryGetValue(CacheKeys.Entry, out cacheEntry))
       {
           // Key not in cache, so get data.
           cacheEntry = DateTime.Now;

           // Set cache options.
           var cacheEntryOptions = new MemoryCacheEntryOptions()
           // Keep in cache for this time, reset time if accessed.
                .SetSlidingExpiration(TimeSpan.FromSeconds(3));

           // Save data in cache.
        _cache.Set(CacheKeys.Entry, cacheEntry, cacheEntryOptions);
      }

      return View("Cache", cacheEntry);
   }

}

更新CacheKeys.Entry是一个静态类,其中定义了所有键。(只是编码标准)。请检查上述文档链接。

public static class CacheKeys
{
   public static string Entry { get { return "_Entry"; } }
   public static string CallbackEntry { get { return "_Callback"; } }
   public static string CallbackMessage { get { return "_CallbackMessage"; } }
   public static string Parent { get { return "_Parent"; } }
   public static string Child { get { return "_Child"; } }
   public static string DependentMessage { get { return "_DependentMessage";} }
   public static string DependentCTS { get { return "_DependentCTS"; } }
   public static string Ticks { get { return "_Ticks"; } }
   public static string CancelMsg { get { return "_CancelMsg"; } }
   public static string CancelTokenSource { get { return "_CancelTokenSource";} }   
}

推荐阅读