郝 玉华

郝 玉华

1655811961

.NET Core API 中实现内存缓存

我们将讨论 .NET Core 中的缓存及其工作原理。所以,我们一一来看以下内容。

  • 缓存介绍
  • 什么是缓存
  • 缓存类型
  • 缓存实现

所以,让我们一个一个开始。

介绍

缓存如今在软件行业非常流行,因为它可以提高应用程序的性能和可扩展性,因为我们使用并看到了许多 Web 应用程序,例如 G-mail 和 Facebook,以及它们的响应速度和我们使用它们时的出色用户体验。有很多用户使用互联网,如果应用程序具有巨大的网络流量和需求,因此我们需要处理许多有助于我们提高应用程序性能和响应能力的事情。因此,正因为如此,其中一种解决方案是缓存,这就是缓存出现的原因。

什么是缓存?

缓存是用于将频繁访问的数据存储到临时存储中的内存存储,它将极大地提高性能并避免不必要的数据库命中,并在需要时将频繁使用的数据存储到缓冲区中。

正如您在上图中看到的,有两种情况,一种是不使用缓存,另一种是使用缓存以及它是如何工作的。所以这里当我们不使用缓存时,假设用户想要数据,那么他们每次都会访问数据库,这会增加时间复杂度并降低性能。如果有一些用户想要的静态数据并且对所有用户都是一样的,在这种情况下,当我们不使用缓存时,每个人都会点击不必要的数据库来获取数据。另一方面,您可以看到我们是否使用缓存,在这种情况下,如果所有用户都有相同的静态和相同的数据,那么只有第一个用户会访问数据库并获取数据并将其存储到缓存中,然后其他两个用户从缓存中使用它,而无需不必要地访问数据库来获取数据。

缓存类型

基本上,.NET Core 支持两种类型的缓存

  1. 内存缓存
  2. 分布式缓存

当我们使用内存缓存时,在这种情况下,数据存储在应用程序服务器内存中,每当我们需要时,我们就会从中获取数据并在需要的地方使用它。在分布式缓存中,有许多第三方机制,例如 Redis 和许多其他机制。但在本节中,我们将详细研究内存缓存以及它在 .NET Core 中的工作原理。

内存缓存

基本上,内存缓存用于轻量级和小型应用程序,并且在这方面效果很好。它将数据存储到应用程序端的服务器内存中,用户可以在需要时使用它。

内存缓存的优势

  • 当我们使用内存缓存时,用户可以快速获取数据。
  • 它将提高应用程序的性能。
  • 最适合部署在单个服务器上的小型应用程序。

内存缓存的缺点

  • 有时 In-Memory 缓存会增加应用程序的维护
  • 在 In-Memory Cache 中,数据保存在单个服务器上,如果服务器崩溃,则数据会丢失。在某些情况下也很难扩展应用程序。

现在我们将创建一个 .NET Core API,在其中实现缓存并了解其工作原理。

步骤1

创建 .NET Core API Web 应用程序

第2步

在我们的应用程序中逐步安装以下 NuGet 包

  • Microsoft.EntityFrameworkCore
  • Microsoft.EntityFrameworkCore.Design
  • Microsoft.EntityFrameworkCore.SqlServer
  • Microsoft.EntityFrameworkCore.Tools
  • Swashbuckle.AspNetCore
  • 系统.运行时.缓存

第 3 步

创建模型文件夹并在其中创建一个包含详细信息的产品类

namespace MemoryCacheDemo.Model
{
    public class Product
    {
        public int ProductId { get; set; }
        public string ProductName { get; set; }
        public string ProductDescription { get; set; }
        public int Stock { get; set; }
    }
}

第4步

接下来,为数据库相关操作创建 DbContextClass 类,如下所示

using MemoryCacheDemo.Model;
using Microsoft.EntityFrameworkCore;
namespace MemoryCacheDemo.Data {
    public class DbContextClass: DbContext {
        public DbContextClass(DbContextOptions < DbContextClass > options): base(options) {}
        public DbSet < Product > Products {
            get;
            set;
        }
    }
}

第 5 步

现在,我们将创建 ICacheService 接口和 CacheService 类,用于与内存缓存相关的使用。

using System;
using System.Collections.Generic;

namespace MemoryCacheDemo.Cache
{
    public interface ICacheService
    {
        /// <summary>
        /// Get Data using key
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <returns></returns>
        T GetData<T>(string key);

        /// <summary>
        /// Set Data with Value and Expiration Time of Key
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <param name="expirationTime"></param>
        /// <returns></returns>
        bool SetData<T>(string key, T value, DateTimeOffset expirationTime);

        /// <summary>
        /// Remove Data
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        object RemoveData(string key);
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Caching;
namespace MemoryCacheDemo.Cache {
    public class CacheService: ICacheService {
        ObjectCache _memoryCache = MemoryCache.Default;
        public T GetData < T > (string key) {
            try {
                T item = (T) _memoryCache.Get(key);
                return item;
            } catch (Exception e) {
                throw;
            }
        }
        public bool SetData < T > (string key, T value, DateTimeOffset expirationTime) {
            bool res = true;
            try {
                if (!string.IsNullOrEmpty(key)) {
                    _memoryCache.Set(key, value, expirationTime);
                }
            } catch (Exception e) {
                throw;
            }
            return res;
        }
        public object RemoveData(string key) {
            try {
                if (!string.IsNullOrEmpty(key)) {
                    return _memoryCache.Remove(key);
                }
            } catch (Exception e) {
                throw;
            }
            return false;
        }
    }
}

第 6 步

创建ProductController类,创建如下方法如下图

using MemoryCacheDemo.Cache;
using MemoryCacheDemo.Data;
using MemoryCacheDemo.Model;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace MemoryCacheDemo.Controllers {
    [Route("api/[controller]")]
    [ApiController]
    public class ProductController: ControllerBase {
        private readonly DbContextClass _dbContext;
        private readonly ICacheService _cacheService;
        public ProductController(DbContextClass dbContext, ICacheService cacheService) {
                _dbContext = dbContext;
                _cacheService = cacheService;
            }
            [HttpGet("products")]
        public IEnumerable < Product > Get() {
                var cacheData = _cacheService.GetData < IEnumerable < Product >> ("product");
                if (cacheData != null) {
                    return cacheData;
                }
                var expirationTime = DateTimeOffset.Now.AddMinutes(5.0);
                cacheData = _dbContext.Products.ToList();
                _cacheService.SetData < IEnumerable < Product >> ("product", cacheData, expirationTime);
                return cacheData;
            }
            [HttpGet("product")]
        public Product Get(int id) {
                Product filteredData;
                var cacheData = _cacheService.GetData < IEnumerable < Product >> ("product");
                if (cacheData != null) {
                    filteredData = cacheData.Where(x => x.ProductId == id).FirstOrDefault();
                    return filteredData;
                }
                filteredData = _dbContext.Products.Where(x => x.ProductId == id).FirstOrDefault();
                return filteredData;
            }
            [HttpPost("addproduct")]
        public async Task < Product > Post(Product value) {
                var obj = await _dbContext.Products.AddAsync(value);
                _cacheService.RemoveData("product");
                _dbContext.SaveChanges();
                return obj.Entity;
            }
            [HttpPut("updateproduct")]
        public void Put(Product product) {
                _dbContext.Products.Update(product);
                _cacheService.RemoveData("product");
                _dbContext.SaveChanges();
            }
            [HttpDelete("deleteproduct")]
        public void Delete(int Id) {
            var filteredData = _dbContext.Products.Where(x => x.ProductId == Id).FirstOrDefault();
            _dbContext.Remove(filteredData);
            _cacheService.RemoveData("product");
            _dbContext.SaveChanges();
        }
    }
}

第 7 步

在 appsetting.json 中添加 SQL Server 连接字符串

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
    "DefaultConnection": "Data Source=server;Initial Catalog=MemoryCache;User Id=****;Password=***;"
  }
}

第 8 步

接下来,在 Startup 类的 Configure Service 方法中注册 ICacheService 并添加一些与 Swagger 相关的配置来测试我们的 API 端点

using MemoryCacheDemo.Cache;
using MemoryCacheDemo.Data;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.OpenApi.Models;
namespace MemoryCacheDemo {
    public class Startup {
        public Startup(IConfiguration configuration) {
            Configuration = configuration;
        }
        public IConfiguration Configuration {
            get;
        }
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services) {
            services.AddControllers();
            services.AddScoped < ICacheService, CacheService > ();
            services.AddDbContext < DbContextClass > (options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
            services.AddSwaggerGen(c => {
                c.SwaggerDoc("v1", new OpenApiInfo {
                    Title = "MemoryCacheDemo", Version = "v1"
                });
            });
        }
        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env) {
            if (env.IsDevelopment()) {
                app.UseDeveloperExceptionPage();
                app.UseSwagger();
                app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "MemoryCacheDemo v1"));
            }
            app.UseHttpsRedirection();
            app.UseRouting();
            app.UseAuthorization();
            app.UseEndpoints(endpoints => {
                endpoints.MapControllers();
            });
        }
    }
}

第 9 步

使用包管理器控制台中的以下命令执行数据库创建的迁移和数据库更新。

添加迁移“FirstMigration”

更新数据库

因此,当您输入并执行此命令时,它将生成一些与迁移相关的内容,并在 SQL Server 中创建数据库,就像您将连接字符串放入 appsetting.json 中一样

第 10 步

最后,运行应用程序并使用 swagger UI 添加数据,然后检查缓存在产品和产品端点内的工作方式。

基本上,我在控制器中的产品和产品端点中添加了缓存,正如您所看到的,当用户想要获取所有产品的数据时,首先它将检查数据是否存在于内存缓存中以及是否存在在缓存中然后将该数据返回给用户,如果数据不存在于缓存中,那么它将从数据库中获取数据并将其设置到缓存中。所以下次用户将只从缓存中获取它并避免不必要地访问数据库 

此外,当用户想要使用产品 ID 获取数据时,正如您在产品第二端点的控制器中看到的那样,我们从所有产品的缓存中获取数据,然后使用产品 ID 进行过滤,如果存在,则从缓存中返回给用户,如果然后在应用过滤器后从数据库中获取并返回给用户。

因此,正如您在产品控制器的更新、删除和发布端点中看到的那样,我们使用 remove 方法删除缓存中存在的产品密钥数据。因此,您可以根据需要和要求使用许多场景和内存缓存。我只想介绍内存缓存的基础知识以及它在我在这里介绍的 .NET Core 中的工作原理。

此外,在使用缓存时需要注意一种情况,例如假设有两个用户在使用您的应用程序,那么将出现以下情况

  • 当第一个用户发送请求以获取所有产品的数据时,第一个请求来了,然后它将检查数据是否存在于缓存中,如果数据存在于缓存中,则它将获取数据从数据库中并将其设置为缓存。
  • 同时,第二个用户发送请求以获取产品详细信息,然后请求在完成第一个用户的请求之前也访问了数据库,因此第二个用户也访问了数据库以获取产品详细信息。
  • 因此,有一种解决方案可以使用锁定机制,如下所示

添加在类的顶部创建一个锁对象,然后在我下面显示的方法中

private static object _lock = new object();
public IEnumerable < Product > Get() {
    var cacheData = _cacheService.GetData < IEnumerable < Product >> ("product");
    if (cacheData != null) {
        return cacheData;
    }
    lock(_lock) {
        var expirationTime = DateTimeOffset.Now.AddMinutes(5.0);
        cacheData = _dbContext.Products.ToList();
        _cacheService.SetData < IEnumerable < Product >> ("product", cacheData, expirationTime);
    }
    return cacheData;
}

因此,正如您首先看到的那样,我们检查数据是否存在于缓存中,如果数据可用,则返回该数据。接下来,如果内存缓存中不存在该值,那么我们在那里应用锁,然后请求被锁定并进入该部分并从数据库中获取产品详细信息,然后将其设置到缓存中,然后返回数据。因此,当第二个用户在用户的请求完成之前发送请求时。因此,在这种情况下,第二个请求在队列中,在完成第一个用户请求后,第二个请求进入图片

这就是 .NET Core 中的内存缓存。我希望你能理解与此相关的事情。

快乐编码!

来源:https ://www.c-sharpcorner.com/article/implement-in-memory-cache-in-the-net-core-api/

  #aspdotnet #api #csharp #dotnet 

What is GEEK

Buddha Community

 .NET Core API 中实现内存缓存
Einar  Hintz

Einar Hintz

1602560783

jQuery Ajax CRUD in ASP.NET Core MVC with Modal Popup

In this article, we’ll discuss how to use jQuery Ajax for ASP.NET Core MVC CRUD Operations using Bootstrap Modal. With jQuery Ajax, we can make HTTP request to controller action methods without reloading the entire page, like a single page application.

To demonstrate CRUD operations – insert, update, delete and retrieve, the project will be dealing with details of a normal bank transaction. GitHub repository for this demo project : https://bit.ly/33KTJAu.

Sub-topics discussed :

  • Form design for insert and update operation.
  • Display forms in modal popup dialog.
  • Form post using jQuery Ajax.
  • Implement MVC CRUD operations with jQuery Ajax.
  • Loading spinner in .NET Core MVC.
  • Prevent direct access to MVC action method.

Create ASP.NET Core MVC Project

In Visual Studio 2019, Go to File > New > Project (Ctrl + Shift + N).

From new project window, Select Asp.Net Core Web Application_._

Image showing how to create ASP.NET Core Web API project in Visual Studio.

Once you provide the project name and location. Select Web Application(Model-View-Controller) and uncheck HTTPS Configuration. Above steps will create a brand new ASP.NET Core MVC project.

Showing project template selection for .NET Core MVC.

Setup a Database

Let’s create a database for this application using Entity Framework Core. For that we’ve to install corresponding NuGet Packages. Right click on project from solution explorer, select Manage NuGet Packages_,_ From browse tab, install following 3 packages.

Showing list of NuGet Packages for Entity Framework Core

Now let’s define DB model class file – /Models/TransactionModel.cs.

public class TransactionModel
{
    [Key]
    public int TransactionId { get; set; }

    [Column(TypeName ="nvarchar(12)")]
    [DisplayName("Account Number")]
    [Required(ErrorMessage ="This Field is required.")]
    [MaxLength(12,ErrorMessage ="Maximum 12 characters only")]
    public string AccountNumber { get; set; }

    [Column(TypeName ="nvarchar(100)")]
    [DisplayName("Beneficiary Name")]
    [Required(ErrorMessage = "This Field is required.")]
    public string BeneficiaryName { get; set; }

    [Column(TypeName ="nvarchar(100)")]
    [DisplayName("Bank Name")]
    [Required(ErrorMessage = "This Field is required.")]
    public string BankName { get; set; }

    [Column(TypeName ="nvarchar(11)")]
    [DisplayName("SWIFT Code")]
    [Required(ErrorMessage = "This Field is required.")]
    [MaxLength(11)]
    public string SWIFTCode { get; set; }

    [DisplayName("Amount")]
    [Required(ErrorMessage = "This Field is required.")]
    public int Amount { get; set; }

    [DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}")]
    public DateTime Date { get; set; }
}

C#Copy

Here we’ve defined model properties for the transaction with proper validation. Now let’s define  DbContextclass for EF Core.

#asp.net core article #asp.net core #add loading spinner in asp.net core #asp.net core crud without reloading #asp.net core jquery ajax form #asp.net core modal dialog #asp.net core mvc crud using jquery ajax #asp.net core mvc with jquery and ajax #asp.net core popup window #bootstrap modal popup in asp.net core mvc. bootstrap modal popup in asp.net core #delete and viewall in asp.net core #jquery ajax - insert #jquery ajax form post #modal popup dialog in asp.net core #no direct access action method #update #validation in modal popup

Einar  Hintz

Einar Hintz

1602564619

MVC User Registration & Login with ASP.NET Core Identity

User registration and authentication are mandatory in any application when you have little concern about privacy. Hence all most all application development starts with an authentication module. In this article, we will discuss the quickest way to use **ASP.NET Core Identity for User Login and Registration **in a new or existing MVC application.

Sub-topics discussed :

  • How to add ASP.NET Core Identity to MVC application.
  • Customize ASP.NET Core Identity.
  • Identity.UI Design Customization.
  • Next step.

Background

ASP.NET Core Identity is an API, which provides both user interface(UI) and functions for user authentication, registration, authorization, etc. Modules/ APIs like this will really be helpful and fasten the development process. It comes with ASP.NET Core Framework and used in many applications before. Which makes the API more dependable and trustworthy.

ASP.NET Core MVC with user authentication can easily be accomplished using Identity.UI. While creating the MVC project, you just need to select Authentication as Individual User Accounts.

Showing how to create an MVC application with ASP.NET Core Identity API

The rest will be handled by ASP.NET Core Identity UI. It already contains razor view pages and backend codes for an authentication system. But that’s not what we want in most of the cases. we want to customize ASP.NET Core Identity as per our requirement. That’s what we do here.

Create an ASP.NET Core MVC Project

First of all, I will create a brand new ASP.NET Core MVC application without any authentication selected. We could add ASP.NET Core Identity later into the project.

In Visual Studio 2019, Go to File > New > Project (Ctrl + Shift + N). From new project window, select ASP.NET Core Web Application.

Create an ASP.NET Core Web application

Once you provide the project name and location. A new window will be opened as follows, Select _Web Application(Model-View-Controller), _uncheck _HTTPS Configuration _and DO NOT select any authentication method. Above steps will create a brand new ASP.NET Core MVC project.

Select Model View Controller templet under .NET Core

#asp.net core article #asp.net core #add asp.net core identity to existing project #asp.net core identity in mvc #asp.net core mvc login and registration #login and logout in asp.net core

Create Asp Net Web API for CRUD operation | CRUD Using Asp Net Api

#api #api 2 #restful api #asp.net api #asp.net core api

Authorization in asp.net core

#Asp.net core #Asp.net core mvc #Core #Asp.net core tutorials #Asp.net core with entity framework

AllowAnonymous in asp.net core

#Asp.net core #Asp.net core mvc #Core #Asp.net core tutorials #Asp.net core with entity framework