ASP.NET

ASP.NET

ASP.NET is an open-source server-side web application framework designed for web development to produce dynamic web pages. It was developed by Microsoft to allow programmers to build dynamic web sites, web applications and web services.

Simple Easy Way Of Creating PDF into Asp.net Core Project Free.

Simple Easy Way of creating PDF into asp.net core Project Free. Create and Download PDF in asp.net core. PDF Example ASP.NET Core.
Source Code : https://payhip.com/b/Gdg6Y

#aspdotnet 

Simple Easy Way Of Creating PDF into Asp.net Core Project Free.
Coding  Life

Coding Life

1656043573

How to Authentication and Authorization in ASP.NET Core | Login and Registration

In this video, we will create an ASP.NET Core 5 web application using Razor Pages and we will implement ASP.NET core Authentication and Authorization using ASP.NET Core Identity. 
We will use Entity Framework Core and SQL Server to store our registered users in our Authentication database.

Chapters:
00:00 Introduction
01:06 Create ASP.NET Core 5 Razor Web Application
02:32 Update to Bootstrap 5
03:40 Discussing Approach
05:40 Install Entity Framework Core (Code First Approach)
10:30 Change Startup.cs to add Authentication
12:00 Create Entity Framework Migrations
13:49 Create and Implement Register page
30:15 Change Navigation Menu in the Layout file
36:10 Create and Implement Login page
48:40 Create and Implement Logout page
54:10 Add Authorization to pages

NuGet Packages to Install
Microsoft.Entityframeworkcore.SqlServer
Microsoft.Entityframeworkcore.Tools
Microsoft.AspNetCore.Identity.EntityFrameworkCore

Entity Framework Core Migrations to run
Add-Database AddAuthentication
Update-Database

☕ Buy me a coffee: https://www.buymeacoffee.com/SameerSaini 

Subscribe: https://www.youtube.com/c/SameerSaini/featured 

#aspdotnet #sql 

How to Authentication and Authorization in ASP.NET Core | Login and Registration
Coding  Life

Coding Life

1656043060

How to Make a REST API using ASP.NET Core and Entity Framework Core

In this tutorial, we will learn how to make a REST API using ASP.NET Core and Entity Framework Core.

We will write CRUD operations (Create, Read, Update, and Delete).

We will use GET, POST, DELETE, and PATCH HTTP Operations in a RESTful .NET Core 3.1 Web API.

We will also integrate our application with Entity Framework Core and store our data in SQL Server database using EF Core.

We will use dependency injection for our restful API and follow SOLID principles to achieve clean code.

👉 Buy me a coffee:
https://www.buymeacoffee.com/SameerSaini

Subscribe: https://www.youtube.com/c/SameerSaini/featured 

#aspdotnet #restapi 

How to Make a REST API using ASP.NET Core and Entity Framework Core

Angular 14 CRUD with .NET 6 Web API | Create an Angular 14 Web Application

Angular 14 CRUD with .NET 6 Web API using Entity Framework Core - Full Course

In this video, we will create an Angular 14 web application using Angular's latest version.
We will perform Angular CRUD operations.
As our API we will use ASP.NET Core or .NET 6 to create a Web API from scratch.
This will be a great full-stack web application using two of the greatest languages i.e. Angular and ASP.NET
In our ASP.NET 6 Web API, we will use entity framework core and SQL Server to perform our CRUD operations.
We will create a new database from scratch using EF Core migrations.
In our Angular 14 application, we will create multiple components and we will set up routing for these components as well.
We will use Bootstrap 5 in our Angular website to make beautiful web components.

Contents:
00:00:00 Introduction
00:00:30 Demo
00:01:30 Update To Angular 14 and .NET 6
00:04:50 Create Angular 14 Application
00:10:48 Install Bootstrap
00:11:50 Add Navbar
00:14:40 Create Employees Component
00:30:10 Create .NET 6 Web API
00:32:24 Install EF Core
00:44:00 Create .NET 6 Controller
00:55:20 Call Web API from Angular app
01:04:10 Enable CORS in API
01:09:44 Add Employee Component
01:29:30 View/Edit Employee Component and API Method
01:51:20 Delete Employee Functionality  

☕ Buy me a coffee: https://www.buymeacoffee.com/SameerSaini 

Subscribe: https://www.youtube.com/c/SameerSaini/featured 

#angular #aspdotnet 

Angular 14 CRUD with .NET 6 Web API  | Create an Angular 14 Web Application
郝 玉华

郝 玉华

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 

 .NET Core API 中实现内存缓存
Rui  Silva

Rui Silva

1655811840

Implementar O Cache De Memória Na API Do .NET Core

Vamos discutir o cache no .NET Core e como ele funciona. Então, vamos olhar para as seguintes coisas, uma por uma.

  • Introdução ao cache
  • O que é Cache
  • Tipos de cache
  • Implementação de cache

Então, vamos começar um por um.

Introdução

O cache é muito popular hoje em dia na indústria de software porque melhorará o desempenho e a escalabilidade do aplicativo, pois usamos e vemos muitos aplicativos da Web como G-mail e Facebook e como eles são responsivos e ótima experiência do usuário enquanto usamos isso. Há muitos usuários usando a internet e se um aplicativo tem grande tráfego de rede e demanda e por isso precisamos cuidar de muitas coisas que nos ajudam a melhorar o desempenho e a capacidade de resposta do aplicativo. Então, por causa disso, uma das soluções é o cache e é por isso que o cache entra em cena.

O que é cache?

O cache é o armazenamento de memória que é usado para armazenar os dados de acesso frequente no armazenamento temporário, melhorará drasticamente o desempenho e evitará o acerto desnecessário do banco de dados e armazenará os dados usados ​​com frequência no buffer sempre que precisarmos.

Como você vê na imagem acima existem dois cenários um é sem usar cache e outro é com cache e como funciona. Então aqui quando não usamos o cache, nesse caso, suponha que os usuários queiram dados, então eles acessarão o banco de dados a cada vez e isso aumentará a complexidade do tempo e reduzirá o desempenho. Caso haja alguns dados estáticos que os usuários desejam e é o mesmo para todos os usuários, nesse caso, quando não usamos o cache, cada um atinge o banco de dados desnecessário para buscar dados. E por outro lado, como você pode ver, se usarmos cache e, nesse caso, se houver os mesmos dados estáticos e iguais para todos os usuários, apenas o primeiro usuário acessará o banco de dados e buscará os dados e os armazenará na memória cache e depois outros dois usuários usam isso do cache sem acessar desnecessariamente o banco de dados para buscar dados.

Tipos de cache

Basicamente, existem dois tipos de suporte a cache do .NET Core

  1. Cache na memória
  2. Cache distribuído

Quando usamos o In-Memory Cache, nesse caso, os dados são armazenados na memória do servidor de aplicativos e, sempre que precisamos, buscamos os dados e os usamos onde quer que precisemos. E no Distributed Caching existem muitos mecanismos de terceiros como Redis e muitos outros. Mas nesta seção, examinamos o Cache de Memória em detalhes e como ele funciona no .NET Core.

Cache na memória

Basicamente, o In-Memory Cache é usado para aplicativos leves e pequenos e funcionará bem nisso. Ele armazena dados na memória do servidor no lado do aplicativo e os usuários os usam sempre que necessário.

Vantagens do cache na memória

  • Os usuários buscam dados rapidamente quando usamos o In-Memory Cache.
  • Isso aumentará o desempenho do aplicativo.
  • Mais adequado para pequenos aplicativos implantados em um único servidor.

Desvantagens do cache na memória

  • Às vezes, o cache na memória aumenta a manutenção do aplicativo
  • No In-Memory Cache, os dados são mantidos em um único servidor e, se o servidor travar, os dados serão perdidos. Também é difícil dimensionar o aplicativo em alguns cenários.

Agora vamos criar uma API .NET Core, implementar o cache nela e entender como as coisas vão funcionar.

Passo 1

Criar o aplicativo Web da API do .NET Core

Passo 2

Instale os seguintes pacotes NuGet que precisam passo a passo em nosso aplicativo

  • Microsoft.EntityFrameworkCore
  • Microsoft.EntityFrameworkCore.Design
  • Microsoft.EntityFrameworkCore.SqlServer
  • Microsoft.EntityFrameworkCore.Tools
  • Swashbuckle.AspNetCore
  • System.Runtime.Caching

etapa 3

Crie a pasta Model e crie uma classe de produto dentro dela com detalhes

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; }
    }
}

Passo 4

Em seguida, crie a classe DbContextClass para operações relacionadas ao banco de dados como mostrei abaixo

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;
        }
    }
}

Etapa 5

Agora, vamos criar a Interface ICacheService e a Classe CacheService para uso relacionado ao Cache In-Memory.

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;
        }
    }
}

Etapa 6

Crie a classe ProductController, crie o seguinte método conforme mostrado abaixo

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();
        }
    }
}

Etapa 7

Adicione a string de conexão do SQL Server dentro de appsetting.json

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

Etapa 8

Em seguida, registre o ICacheService dentro do método Configure Service da Startup Class e também adicione algumas configurações relacionadas ao Swagger para testar nossos endpoints da 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();
            });
        }
    }
}

Etapa 9

Execute migração e atualização de banco de dados para criação de banco de dados usando os comandos a seguir no console do gerenciador de pacotes.

add-migration “FirstMigration”

atualizar o banco de dados

Então, quando você inserir e executar este comando, ele gerará algumas coisas relacionadas à migração e criará o banco de dados dentro do SQL Server conforme você coloca dentro da Connection String no appsetting.json

Etapa 10

Por fim, execute o aplicativo e adicione os dados usando a interface do usuário do swagger e, em seguida, verifique como o armazenamento em cache funciona nos produtos e no endpoint do produto.

Basicamente, adicionei cache nos endpoints do produto e produtos no controlador, como você vê quando o usuário deseja buscar dados de todos os produtos, primeiro ele verificará se os dados estão presentes dentro do Cache In-Memory ou não e se estão presentes dentro do cache, em seguida, retorne esses dados para o usuário e, se os dados não estiverem presentes dentro do cache, ele buscará os dados do banco de dados e também os definirá no cache. Então, da próxima vez, o usuário obterá isso apenas do cache e evitará acessar o banco de dados desnecessariamente 

Além disso, quando o usuário deseja buscar dados usando o ID do produto como você vê no controlador no segundo endpoint do produto, buscamos dados do cache de todos os produtos e filtramos usando o ID do produto e, se estiver presente, retornamos ao usuário do cache e se não buscar no banco de dados e retornar ao usuário após aplicar o filtro.

Então, como você vê dentro de update, delete e post endpoint do Product Controller, então usamos o método remove para remover os dados da chave do produto que está presente dentro do cache. Portanto, existem muitos cenários e uso de caches de memória que você pode usar de acordo com sua necessidade e requisitos. Eu só quero apresentar o básico do Cache de Memória e como ele funciona dentro do .NET Core que eu abordei aqui.

Além disso, há um cenário que você precisa cuidar ao usar o cache, como suponha, há dois usuários usando seu aplicativo, então os seguintes cenários virão

  • Quando o primeiro usuário envia a requisição para buscar os dados de todos os produtos então vem a primeira requisição e então ele vai checar se os dados estão presentes dentro do cache ou não e se os dados estão presentes dentro do cache, então ele vai buscar os dados do banco de dados e também configurá-lo para o cache.
  • Enquanto isso, o segundo usuário envia a solicitação para obter os detalhes do produto, então a solicitação também atinge o banco de dados antes de concluir a solicitação do primeiro usuário e, por causa desse segundo usuário, também acessa o banco de dados para buscar os detalhes do produto.
  • Portanto, existe uma solução para isso usar o mecanismo de bloqueio, conforme mostrado abaixo

Adicione crie um objeto de bloqueio no topo da classe e depois no método como mostrei abaixo

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;
}

Então aqui, como você vê primeiro, verificamos se os dados estão presentes dentro do cache ou não, se os dados estão disponíveis e retornamos isso. Em seguida, se o valor não estiver presente no cache de memória, aplicamos o bloqueio ali e, em seguida, a solicitação é bloqueada e inserida na seção e buscamos os detalhes do produto no banco de dados, e também configuramos para o cache e, em seguida, retornar os dados. Portanto, quando o segundo usuário envia uma solicitação antes que a solicitação do usuário seja concluída. Então, nesse caso, a segunda solicitação está na fila e depois de concluir a primeira solicitação do usuário, a segunda solicitação entra em cena

Isso é tudo sobre Cache de Memória no .NET Core. Espero que você entenda as coisas relacionadas a isso.

Boa Codificação!

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

  #aspdotnet #api #csharp #dotnet 

Implementar O Cache De Memória Na API Do .NET Core

Implementar Caché En Memoria En La API De .NET Core

Vamos a discutir el almacenamiento en caché en .NET Core y cómo funciona. Entonces, miramos las siguientes cosas una por una.

  • Introducción del almacenamiento en caché
  • ¿Qué es el caché?
  • Tipos de caché
  • Implementación de caché

Entonces, comencemos uno por uno.

Introducción

El almacenamiento en caché es muy popular hoy en día en la industria del software porque mejorará el rendimiento y la escalabilidad de la aplicación, ya que usamos y vemos muchas aplicaciones web como G-mail y Facebook y cuán receptivas son y una gran experiencia de usuario mientras las usamos. Hay muchos usuarios que usan Internet y si una aplicación tiene un gran tráfico y demanda en la red, debemos ocuparnos de muchas cosas que nos ayudan a mejorar el rendimiento y la capacidad de respuesta de la aplicación. Entonces, debido a eso, una de las soluciones es el almacenamiento en caché y es por eso que el almacenamiento en caché entra en escena.

¿Qué es el almacenamiento en caché?

El caché es el almacenamiento de memoria que se utiliza para almacenar los datos de acceso frecuente en el almacenamiento temporal, mejorará drásticamente el rendimiento y evitará el acceso innecesario a la base de datos y almacenará los datos de uso frecuente en el búfer cuando lo necesitemos.

Como puede ver en la imagen de arriba, hay dos escenarios, uno sin usar caché y otro con caché y cómo funciona. Entonces, aquí, cuando no usamos el caché, en ese caso, supongamos que los usuarios quieren datos, entonces accederán cada vez a la base de datos y aumentará la complejidad del tiempo y reducirá el rendimiento. En caso de que haya algunos datos estáticos que los usuarios deseen y sea lo mismo para todos los usuarios, en ese caso, cuando no usamos el caché, cada uno accede a la base de datos innecesaria para obtener datos. Y por otro lado, como puede ver, si usamos caché y, en ese caso, si hay los mismos datos estáticos y los mismos para todos los usuarios, solo el primer usuario accederá a la base de datos y obtendrá datos y los almacenará en la memoria caché y luego otro dos usuarios usan eso desde el caché sin presionar innecesariamente la base de datos para obtener datos.

Tipos de caché

Básicamente, hay dos tipos de almacenamiento en caché compatibles con .NET Core

  1. Almacenamiento en caché en memoria
  2. Almacenamiento en caché distribuido

Cuando usamos In-Memory Cache, en ese caso, los datos se almacenan en la memoria del servidor de aplicaciones y, siempre que los necesitamos, extraemos datos de eso y los usamos donde los necesitemos. Y en el almacenamiento en caché distribuido hay muchos mecanismos de terceros como Redis y muchos otros. Pero en esta sección, analizamos en detalle la memoria caché en memoria y cómo funciona en .NET Core.

Caché en memoria

Básicamente, In-Memory Cache se usa para aplicaciones ligeras y pequeñas y funcionará bien en eso. Almacena datos en la memoria del servidor en el lado de la aplicación y los usuarios los usan cuando surge la necesidad.

Ventajas de la memoria caché en memoria

  • Los usuarios obtienen datos rápidamente cuando usamos In-Memory Cache.
  • Aumentará el rendimiento de la aplicación.
  • Ideal para aplicaciones pequeñas que se implementan en un solo servidor.

Desventajas de la memoria caché en memoria

  • En ocasiones, la memoria caché en memoria aumenta el mantenimiento de la aplicación
  • En In-Memory Cache, los datos se conservan en un solo servidor y, si el servidor falla, los datos se pierden. Además, es difícil escalar la aplicación en algunos escenarios.

Ahora vamos a crear una API de .NET Core, implementar el almacenamiento en caché y comprender cómo funcionarán las cosas.

Paso 1

Crear la aplicación web de la API de .NET Core

Paso 2

Instale los siguientes paquetes NuGet que necesitan paso a paso en nuestra aplicación

  • Microsoft.EntityFrameworkCore
  • Microsoft.EntityFrameworkCore.Diseño
  • Microsoft.EntityFrameworkCore.SqlServer
  • Microsoft.EntityFrameworkCore.Herramientas
  • Swashbuckle.AspNetCore
  • System.Runtime.Caching

Paso 3

Cree la carpeta Modelo y cree una Clase de producto dentro con detalles

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; }
    }
}

Paso 4

A continuación, cree la clase DbContextClass para las operaciones relacionadas con la base de datos como se muestra a continuación

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;
        }
    }
}

Paso 5

Ahora, vamos a crear la interfaz ICacheService y la clase CacheService para el uso relacionado con In-Memory Cache.

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;
        }
    }
}

Paso 6

Cree la clase ProductController, cree el siguiente método como se muestra a continuación

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();
        }
    }
}

Paso 7

Agregue la cadena de conexión de SQL Server dentro de appsetting.json

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

Paso 8

A continuación, registre ICacheService dentro del método Configure Service de Startup Class y también agregue alguna configuración relacionada con Swagger para probar nuestros puntos finales de 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();
            });
        }
    }
}

Paso 9

Realice la migración y la actualización de la base de datos para la creación de la base de datos mediante los siguientes comandos en la consola del administrador de paquetes.

agregar-migración "Primera migración"

actualizar base de datos

Entonces, cuando ingrese y ejecute este comando, generará algunas cosas relacionadas con la migración y creará la base de datos dentro de SQL Server a medida que ingresa la Cadena de conexión en appsetting.json

Paso 10

Finalmente, ejecute la aplicación y agregue los datos usando la interfaz de usuario de Swagger y luego verifique cómo funciona el almacenamiento en caché dentro de los productos y el punto final del producto.

Básicamente, agregué caché en el producto y los puntos finales de los productos en el controlador, como puede ver cuando el usuario desea obtener datos de todos los productos, primero verificará si los datos están presentes dentro del In-Memory Cache o no y si está presente dentro del caché, luego devuelva esos datos al usuario y, si los datos no están presentes dentro del caché, obtendrá los datos de la base de datos y también los configurará en el caché. Entonces, la próxima vez, el usuario obtendrá eso solo del caché y evitará acceder a la base de datos innecesariamente. 

Además, cuando el usuario desea obtener datos utilizando la identificación del producto como se ve en el controlador en el segundo punto final del producto, obtenemos datos de la memoria caché de todos los productos, luego filtramos usando la identificación del producto y, si está presente, regresamos al usuario desde la memoria caché y si luego no obtener de la base de datos y regresar al usuario después de aplicar el filtro.

Entonces, como puede ver en el interior, actualice, elimine y publique el punto final del controlador del producto, luego usamos el método de eliminación para eliminar los datos de la clave del producto que está presente dentro del caché. Por lo tanto, hay muchos escenarios y usos de cachés de memoria que puede usar según sus necesidades y requisitos. Solo quiero presentar los conceptos básicos de Memory Cache y cómo funciona dentro de .NET Core que cubrí aquí.

Además, hay un escenario del que debe ocuparse al usar el almacenamiento en caché como supongamos, hay dos usuarios que usan su aplicación, luego vendrán los siguientes escenarios

  • Cuando el primer usuario envía la solicitud para obtener los datos de todos los productos, llega la primera solicitud y luego verificará si los datos están presentes dentro del caché o no y si los datos están presentes dentro del caché, luego obtendrá los datos. de la base de datos y también configurarlo en el caché.
  • Mientras tanto, el segundo usuario envía la solicitud para obtener los detalles del producto, luego la solicitud también ingresa a la base de datos antes de completar la solicitud del primer usuario y debido a que el segundo usuario también ingresa a la base de datos para obtener los detalles del producto.
  • Entonces, hay una solución para esto para usar el mecanismo de bloqueo como se muestra a continuación

Agregue crear un objeto de bloqueo en la parte superior de la clase y luego en el método como se muestra a continuación

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;
}

Entonces, como puede ver primero, verificamos si los datos están presentes dentro del caché o no, si los datos están disponibles y luego los devolvemos. A continuación, si el valor no está presente en la caché de memoria, aplicamos el bloqueo allí y luego la solicitud se bloquea y se ingresa en la sección y se obtienen los detalles del producto de la base de datos, y luego también se establece en la memoria caché y luego devolver los datos. Entonces, cuando el segundo usuario envía una solicitud antes de que la solicitud del usuario esté completa. Entonces, en ese caso, la segunda solicitud está en la cola y después de completar la primera solicitud del usuario, la segunda solicitud aparece en la imagen.

Esto es todo acerca de In-Memory Cache en .NET Core. Espero que entiendas cosas relacionadas con eso.

¡Feliz codificación!

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

  #aspdotnet #api #csharp #dotnet 

Implementar Caché En Memoria En La API De .NET Core
Hoang  Ha

Hoang Ha

1655811600

Triển Khai Bộ Nhớ Đệm Trong Bộ Nhớ Trong .NET Core API

Chúng ta sẽ thảo luận về bộ nhớ đệm trong .NET Core và cách thức hoạt động của nó. Vì vậy, chúng ta xem xét từng thứ sau đây.

  • Giới thiệu về bộ nhớ đệm
  • Cache là gì
  • Các loại bộ nhớ đệm
  • Triển khai bộ nhớ đệm

Vì vậy, chúng ta hãy bắt đầu từng cái một.

Giới thiệu

Bộ nhớ đệm ngày nay rất phổ biến trong ngành công nghiệp phần mềm vì nó sẽ cải thiện hiệu suất và khả năng mở rộng của ứng dụng, khi chúng tôi sử dụng và thấy nhiều ứng dụng web như G-mail và Facebook cũng như mức độ phản hồi của chúng và trải nghiệm người dùng tuyệt vời khi chúng tôi sử dụng ứng dụng đó. Có rất nhiều người dùng sử dụng Internet và nếu một ứng dụng có lưu lượng và nhu cầu mạng lớn và do đó chúng ta cần quan tâm đến nhiều thứ để giúp chúng ta cải thiện hiệu suất và khả năng phản hồi của ứng dụng. Vì vậy, do đó, có một trong những giải pháp là bộ nhớ đệm và đó là lý do bộ nhớ đệm xuất hiện trong bức tranh.

Bộ nhớ đệm là gì?

Bộ nhớ đệm là bộ nhớ lưu trữ được sử dụng để lưu trữ dữ liệu truy cập thường xuyên vào bộ lưu trữ tạm thời, nó sẽ cải thiện hiệu suất đáng kể và tránh bị tấn công cơ sở dữ liệu không cần thiết và lưu trữ dữ liệu thường xuyên sử dụng vào bộ đệm bất cứ khi nào chúng ta cần.

Như bạn thấy trong hình trên, có hai tình huống một là không sử dụng bộ đệm và một là với bộ đệm và cách nó hoạt động. Vì vậy, ở đây khi chúng ta không sử dụng bộ nhớ cache, trong trường hợp đó, giả sử người dùng muốn có dữ liệu thì họ sẽ đánh mỗi lần cơ sở dữ liệu và nó sẽ làm tăng thời gian phức tạp và giảm hiệu suất. Trong trường hợp có một số dữ liệu tĩnh người dùng muốn và nó giống nhau cho tất cả người dùng, trong trường hợp đó khi chúng ta không sử dụng bộ nhớ cache thì mỗi người đánh vào cơ sở dữ liệu không cần thiết để tìm nạp dữ liệu. Và ở mặt khác, như bạn có thể thấy nếu chúng tôi sử dụng bộ nhớ cache và trong trường hợp đó, nếu có cùng một dữ liệu tĩnh và giống nhau cho tất cả người dùng thì chỉ người dùng đầu tiên sẽ truy cập cơ sở dữ liệu và tìm nạp dữ liệu và lưu trữ vào bộ nhớ đệm, sau đó khác hai người dùng sử dụng nó từ bộ nhớ cache mà không cần nhấn vào cơ sở dữ liệu để tìm nạp dữ liệu một cách không cần thiết.

Các loại bộ nhớ đệm

Về cơ bản, có hai loại bộ nhớ đệm .NET Core hỗ trợ

  1. Bộ nhớ đệm trong bộ nhớ
  2. Bộ nhớ đệm phân tán

Khi chúng tôi sử dụng In-Memory Cache thì trong trường hợp đó, dữ liệu được lưu trữ trong bộ nhớ của máy chủ ứng dụng và bất cứ khi nào chúng tôi cần thì chúng tôi tìm nạp dữ liệu từ đó và sử dụng nó ở bất cứ đâu chúng tôi cần. Và trong Bộ đệm ẩn phân tán có nhiều cơ chế của bên thứ ba như Redis và nhiều cơ chế khác. Nhưng trong phần này, chúng tôi xem xét chi tiết Bộ nhớ đệm trong bộ nhớ và cách nó hoạt động trong .NET Core.

Bộ nhớ đệm trong bộ nhớ

Về cơ bản, In-Memory Cache được sử dụng cho các ứng dụng nhẹ và nhỏ và sẽ hoạt động tốt trong đó. Nó lưu trữ dữ liệu vào bộ nhớ máy chủ ở phía ứng dụng và người dùng sử dụng nó bất cứ khi nào có nhu cầu.

Ưu điểm của bộ nhớ đệm trong bộ nhớ

  • Người dùng tìm nạp dữ liệu nhanh chóng khi chúng tôi sử dụng In-Memory Cache.
  • Nó sẽ làm tăng hiệu suất của ứng dụng.
  • Phù hợp nhất cho ứng dụng nhỏ được triển khai trên một máy chủ duy nhất.

Nhược điểm của bộ nhớ đệm trong bộ nhớ

  • Đôi khi bộ nhớ đệm trong bộ nhớ làm tăng khả năng bảo trì của ứng dụng
  • Trong bộ nhớ đệm trong bộ nhớ, dữ liệu được lưu trữ trên một máy chủ duy nhất và nếu máy chủ gặp sự cố thì dữ liệu sẽ bị mất. Ngoài ra, thật khó để mở rộng ứng dụng trong một số trường hợp.

Bây giờ chúng ta sẽ tạo một .NET Core API, triển khai bộ nhớ đệm vào đó và hiểu mọi thứ sẽ hoạt động như thế nào.

Bước 1

Tạo ứng dụng web .NET Core API

Bước 2

Cài đặt các Gói NuGet sau đây cần từng bước trong ứng dụng của chúng tôi

  • Microsoft.EntityFrameworkCore
  • Microsoft.EntityFrameworkCore.Design
  • Microsoft.EntityFrameworkCore.SqlServer
  • Microsoft.EntityFrameworkCore.Tools
  • Swashbuckle.AspNetCore
  • System.Runtime.Caching

Bước 3

Tạo thư mục Model và tạo một Lớp Sản phẩm bên trong với các chi tiết

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; }
    }
}

Bước 4

Tiếp theo, Tạo Lớp DbContextClass cho các hoạt động liên quan đến Cơ sở dữ liệu như tôi đã trình bày bên dưới

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;
        }
    }
}

Bước 5

Bây giờ, chúng ta sẽ tạo Giao diện ICacheService và Lớp CacheService để sử dụng liên quan đến Bộ nhớ cache trong bộ nhớ.

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;
        }
    }
}

Bước 6

Tạo lớp ProductController, tạo phương thức sau như hình bên dưới

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();
        }
    }
}

Bước 7

Thêm chuỗi kết nối SQL Server bên trong appsetting.json

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

Bước 8

Tiếp theo, Đăng ký ICacheService bên trong phương thức Cấu hình Dịch vụ của Lớp Khởi động và cũng thêm một số cấu hình liên quan đến Swagger để kiểm tra các điểm cuối API của chúng tôi

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();
            });
        }
    }
}

Bước 9

Thực hiện Di chuyển và Cập nhật Cơ sở dữ liệu cho Tạo DB bằng các lệnh sau trong Bảng điều khiển Trình quản lý Gói.

add -igration “FirstMigration”

cập nhật cơ sở dữ liệu

Vì vậy, khi bạn nhập và thực thi lệnh này, nó sẽ tạo ra một số thứ liên quan đến việc di chuyển và tạo cơ sở dữ liệu bên trong SQL Server khi bạn đặt bên trong Chuỗi kết nối trong appsetting.json

Bước 10

Cuối cùng, chạy ứng dụng và thêm dữ liệu bằng giao diện người dùng swagger và sau đó kiểm tra cách bộ nhớ đệm hoạt động bên trong sản phẩm và điểm cuối của sản phẩm.

Về cơ bản, tôi đã thêm bộ nhớ cache vào sản phẩm và các điểm cuối của sản phẩm trong bộ điều khiển, như bạn thấy khi người dùng muốn tìm nạp dữ liệu của tất cả các sản phẩm thì trước tiên, nó sẽ kiểm tra xem dữ liệu có bên trong Bộ nhớ đệm trong bộ nhớ hay không và nếu nó có mặt bên trong bộ đệm, sau đó trả lại dữ liệu đó cho người dùng và nếu dữ liệu không có bên trong bộ đệm, thì nó sẽ tìm nạp dữ liệu từ cơ sở dữ liệu và cũng có thể đặt dữ liệu đó vào bộ đệm. Vì vậy, lần sau người dùng sẽ chỉ nhận được điều đó từ bộ nhớ cache và tránh đánh vào cơ sở dữ liệu một cách không cần thiết 

Ngoài ra, khi người dùng muốn tìm nạp dữ liệu bằng cách sử dụng id sản phẩm như bạn thấy trong bộ điều khiển ở điểm cuối thứ hai của sản phẩm, chúng tôi tìm nạp dữ liệu từ bộ nhớ cache của tất cả các sản phẩm, sau đó lọc bằng id sản phẩm và nếu có thì trả về người dùng từ bộ nhớ cache và nếu sau đó không tìm nạp từ cơ sở dữ liệu và trở lại người dùng sau khi áp dụng bộ lọc.

Vì vậy, như bạn thấy bên trong cập nhật, xóa và đăng điểm cuối của Bộ điều khiển sản phẩm, sau đó chúng tôi sử dụng phương pháp loại bỏ để xóa dữ liệu của khóa sản phẩm có bên trong bộ nhớ cache. Vì vậy, có rất nhiều tình huống và cách sử dụng bộ nhớ đệm mà bạn có thể sử dụng tùy theo nhu cầu và yêu cầu của mình. Tôi chỉ muốn giới thiệu những điều cơ bản về Memory Cache và cách nó hoạt động bên trong .NET Core mà tôi đã trình bày ở đây.

Ngoài ra, có một tình huống bạn cần quan tâm khi sử dụng bộ nhớ đệm, chẳng hạn như giả sử, có hai người dùng sử dụng ứng dụng của bạn thì các tình huống sau sẽ xảy ra

  • Khi người dùng đầu tiên gửi yêu cầu tìm nạp dữ liệu của tất cả các sản phẩm thì yêu cầu đầu tiên sẽ đến và sau đó nó sẽ kiểm tra xem dữ liệu có bên trong bộ đệm hay không và nếu dữ liệu có bên trong bộ đệm, thì nó sẽ tìm nạp dữ liệu. từ cơ sở dữ liệu và cũng đặt nó vào bộ nhớ cache.
  • Trong khi đó, người dùng thứ hai gửi yêu cầu để lấy thông tin chi tiết về sản phẩm thì yêu cầu cũng truy cập vào cơ sở dữ liệu trước khi hoàn thành yêu cầu của người dùng đầu tiên và vì người dùng thứ hai đó cũng truy cập vào cơ sở dữ liệu để lấy chi tiết sản phẩm.
  • Vì vậy, có một giải pháp cho việc này là sử dụng Cơ chế khóa như hình dưới đây

Thêm tạo một đối tượng khóa trên cùng của lớp và sau đó trong phương thức như tôi đã hiển thị bên dưới

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;
}

Vì vậy, ở đây như bạn thấy đầu tiên, chúng tôi kiểm tra xem dữ liệu có bên trong bộ đệm hay không nếu dữ liệu có sẵn thì trả về. Tiếp theo, nếu giá trị không có trong bộ nhớ đệm, thì chúng tôi áp dụng khóa ở đó và sau đó yêu cầu được khóa và nhập vào phần và tìm nạp chi tiết sản phẩm từ cơ sở dữ liệu, sau đó cũng đặt nó vào bộ đệm và sau đó trả lại dữ liệu. Vì vậy, khi người dùng thứ hai gửi yêu cầu trước khi yêu cầu của người dùng đó hoàn tất. Vì vậy, trong trường hợp đó, yêu cầu thứ hai nằm trong hàng đợi và sau khi hoàn thành yêu cầu người dùng đầu tiên, yêu cầu thứ hai xuất hiện trong hình

Đây là tất cả về Bộ nhớ đệm trong Bộ nhớ trong .NET Core. Tôi hy vọng bạn hiểu những điều liên quan đến điều đó.

Nguồn: https://www.c-sharpcorner.com/article/implement-in-memory-cache-in-the-net-core-api/

 #aspdotnet #api #csharp #dotnet 

Triển Khai Bộ Nhớ Đệm Trong Bộ Nhớ Trong .NET Core API
伊藤  直子

伊藤 直子

1655811200

.NETCoreAPIにインメモリキャッシュを実装する

.NETCoreでのキャッシングとその仕組みについて説明します。そこで、以下のことを一つ一つ見ていきます。

  • キャッシングの紹介
  • キャッシュとは
  • キャッシュの種類
  • キャッシュの実装

それでは、1つずつ始めましょう。

序章

キャッシングは、GメールやFacebookなどの多くのWebアプリケーションを使用して確認し、それらの応答性と優れたユーザーエクスペリエンスを使用することで、アプリケーションのパフォーマンスとスケーラビリティが向上するため、今日のソフトウェア業界で非常に人気があります。インターネットを使用しているユーザーはたくさんいます。アプリケーションに膨大なネットワークトラフィックと需要がある場合、そのため、アプリケーションのパフォーマンスと応答性を向上させるのに役立つ多くのことに注意を払う必要があります。そのため、解決策の1つがキャッシングであり、それがキャッシングが登場する理由です。

キャッシングとは何ですか?

キャッシュは、頻繁にアクセスするデータを一時ストレージに格納するために使用されるメモリストレージであり、パフォーマンスを大幅に向上させ、不要なデータベースヒットを回避し、頻繁に使用されるデータを必要なときにバッファに格納します。

上の画像でわかるように、2つのシナリオがあります。1つはキャッシュを使用しない場合、もう1つはキャッシュを使用する場合とその動作です。したがって、ここでキャッシュを使用しない場合、その場合、ユーザーがデータを必要としているとすると、データベースにアクセスするたびにヒットし、時間の複雑さが増し、パフォーマンスが低下します。ユーザーが必要とする静的データがいくつかあり、それがすべてのユーザーに同じである場合、その場合、キャッシュを使用しないと、それぞれが不要なデータベースにアクセスしてデータをフェッチします。反対側では、キャッシュを使用するかどうかを確認できます。その場合、すべてのユーザーに同じ静的データと同じデータがある場合、最初のユーザーのみがデータベースにアクセスしてデータをフェッチし、キャッシュメモリに保存してから他のユーザーに保存します。 2人のユーザーは、データをフェッチするために不必要にデータベースにアクセスすることなく、キャッシュからそれを使用します。

キャッシュの種類

基本的に、.NETCoreがサポートするキャッシングには2つのタイプがあります

  1. インメモリキャッシング
  2. 分散キャッシング

インメモリキャッシュを使用する場合、その場合、データはアプリケーションサーバーのメモリに保存され、必要なときにいつでもそこからデータをフェッチして、必要な場所で使用します。また、分散キャッシングには、Redisやその他の多くのサードパーティメカニズムがあります。ただし、このセクションでは、インメモリキャッシュと、それが.NETCoreでどのように機能するかについて詳しく説明します。

インメモリキャッシュ

基本的に、インメモリキャッシュは軽量で小さなアプリケーションに使用され、その中でうまく機能します。アプリケーション側のサーバーメモリにデータを保存し、ユーザーは必要に応じてそれを使用します。

インメモリキャッシュの利点

  • インメモリキャッシュを使用すると、ユーザーはデータをすばやくフェッチします。
  • アプリケーションのパフォーマンスが向上します。
  • 単一サーバーにデプロイされる小さなアプリケーションに最適です。

インメモリキャッシュのデメリット

  • インメモリキャッシュにより、アプリケーションのメンテナンスが向上する場合があります
  • インメモリキャッシュでは、データは単一のサーバーに保持され、サーバーがクラッシュするとデータは失われます。また、一部のシナリオでは、アプリケーションをスケーリングするのが困難です。

次に、1つの.NET Core APIを作成し、それにキャッシュを実装して、処理がどのように機能するかを理解します。

ステップ1

.NET CoreAPIWebアプリケーションを作成します

ステップ2

アプリケーションに段階的に必要な次のNuGetパッケージをインストールします

  • Microsoft.EntityFrameworkCore
  • Microsoft.EntityFrameworkCore.Design
  • Microsoft.EntityFrameworkCore.SqlServer
  • Microsoft.EntityFrameworkCore.Tools
  • Swashbuckle.AspNetCore
  • System.Runtime.Caching

ステップ3

Modelフォルダーを作成し、その中に詳細を含む1つの製品クラスを作成します

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内にSQLServer接続文字列を追加します

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

ステップ8

次に、スタートアップクラスの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

パッケージマネージャーコンソールで次のコマンドを使用して、DB作成の移行とデータベース更新を実行します。

add-migration「FirstMigration」

データベースを更新する

したがって、このコマンドを入力して実行すると、移行に関連するいくつかのものが生成され、appsetting.jsonの接続文字列内に配置するときにSQLServer内にデータベースが作成されます。

ステップ10

最後に、アプリケーションを実行し、Swagger UIを使用してデータを追加してから、製品および製品エンドポイント内でキャッシュがどのように機能するかを確認します。

基本的に、コントローラーの製品と製品のエンドポイントにキャッシュを追加しました。ユーザーがすべての製品のデータを取得する場合は、最初にデータがインメモリキャッシュ内に存在するかどうか、および存在するかどうかを確認します。次に、キャッシュ内でそのデータをユーザーに返します。データがキャッシュ内に存在しない場合は、データベースからデータをフェッチし、それをキャッシュに設定します。したがって、次回ユーザーはキャッシュからのみそれを取得し、データベースに不必要にアクセスすることを回避します 

また、ユーザーが製品の2番目のエンドポイントのコントローラーに表示される製品IDを使用してデータをフェッチする場合は、すべての製品のキャッシュからデータをフェッチし、製品IDを使用してフィルター処理し、それが存在する場合はキャッシュからユーザーに戻ります。その後、データベースからフェッチして、フィルターを適用した後にユーザーに戻ることはありません。

したがって、Product Controllerのエンドポイントの更新、削除、および投稿の内部を見ると、キャッシュ内に存在するプロダクトキーのデータを削除するためにremoveメソッドを使用します。したがって、必要性と要件に応じて使用できる多くのシナリオとメモリキャッシュの使用があります。ここで取り上げたメモリキャッシュの基本と、.NETCore内でのメモリキャッシュの動作について紹介します。

また、仮定のようにキャッシングを使用しているときに注意する必要があるシナリオが1つあります。アプリケーションを使用しているユーザーが2人いる場合、次のシナリオが発生します。

  • 最初のユーザーがすべての製品のデータをフェッチするリクエストを送信すると、最初のリクエストが送信され、データがキャッシュ内に存在するかどうかがチェックされ、データがキャッシュ内に存在する場合は、データがフェッチされます。データベースから、またそれをキャッシュに設定します。
  • 一方、2番目のユーザーは製品の詳細を取得するためにリクエストを送信し、リクエストは最初のユーザーのリクエストを完了する前にデータベースにもヒットします。そのため、2番目のユーザーもデータベースにヒットして製品の詳細を取得します。
  • したがって、以下に示すように、ロックメカニズムを使用するための1つの解決策があります。

以下に示すように、クラスの最上位にロックオブジェクトを作成してから、メソッドに追加します

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;
}

したがって、ここで最初に見たように、データがキャッシュ内に存在するかどうかを確認し、データが利用可能かどうかを確認してから、それを返します。次に、値がメモリキャッシュに存在しない場合は、そこにロックを適用し、リクエストをロックしてセクションに入力し、データベースから製品の詳細を取得してから、キャッシュに設定します。データを返します。したがって、2番目のユーザーがユーザーの要求が完了する前に要求を送信した場合。したがって、その場合、2番目のリクエストはキューにあり、最初のユーザーリクエストを完了した後、2番目のリクエストが画像に表示されます。

これはすべて、.NETCoreのインメモリキャッシュに関するものです。それに関連することをご理解いただければ幸いです。

ハッピーコーディング!

ソース:https ://www.c-sharpcorner.com/article/implement-in-memory-cache-in-the-net-core-api/

  #aspdotnet #api #csharp #dotnet 

.NETCoreAPIにインメモリキャッシュを実装する

Implémenter Le Cache En Mémoire Dans L'API .NET Core

Nous allons discuter de la mise en cache dans .NET Core et de son fonctionnement. Donc, nous regardons les choses suivantes une par une.

  • Présentation de la mise en cache
  • Qu'est-ce que le cache
  • Types de cache
  • Implémentation du cache

Alors, commençons un par un.

Introduction

La mise en cache est très populaire de nos jours dans l'industrie du logiciel car elle améliorera les performances et l'évolutivité de l'application, car nous utilisons et voyons de nombreuses applications Web comme G-mail et Facebook et leur réactivité et une excellente expérience utilisateur lorsque nous les utilisons. De nombreux utilisateurs utilisent Internet et si une application a un trafic réseau et une demande énormes, nous devons nous occuper de beaucoup de choses qui nous aident à améliorer les performances et la réactivité de l'application. Donc, à cause de cela, l'une des solutions est la mise en cache et c'est pourquoi la mise en cache entre en jeu.

Qu'est-ce que la mise en cache ?

Le cache est le stockage de mémoire utilisé pour stocker les données d'accès fréquentes dans le stockage temporaire, il améliorera considérablement les performances et évitera les accès inutiles à la base de données et stockera les données fréquemment utilisées dans le tampon chaque fois que nous en aurons besoin.

Comme vous le voyez dans l'image ci-dessus, il existe deux scénarios, l'un sans utiliser de cache et l'autre avec cache et son fonctionnement. Donc, ici, lorsque nous n'utilisons pas le cache, dans ce cas, supposons que les utilisateurs veulent des données, ils accéderont à chaque fois à la base de données, ce qui augmentera la complexité temporelle et réduira les performances. Dans le cas où les utilisateurs veulent des données statiques et que c'est la même chose pour tous les utilisateurs, dans ce cas, lorsque nous n'utilisons pas le cache, chacun accède à la base de données inutile pour récupérer des données. Et de l'autre côté, comme vous pouvez le voir si nous utilisons le cache et dans ce cas, s'il existe les mêmes données statiques et identiques pour tous les utilisateurs, seul le premier utilisateur accédera à la base de données, récupèrera les données et les stockera dans la mémoire cache, puis autre deux utilisateurs l'utilisent à partir du cache sans accéder inutilement à la base de données pour récupérer des données.

Types de cache

Fondamentalement, il existe deux types de prise en charge de la mise en cache de .NET Core

  1. Mise en cache en mémoire
  2. Mise en cache distribuée

Lorsque nous utilisons le cache en mémoire, dans ce cas, les données sont stockées dans la mémoire du serveur d'applications et chaque fois que nous en avons besoin, nous récupérons les données et les utilisons partout où nous en avons besoin. Et dans la mise en cache distribuée, il existe de nombreux mécanismes tiers comme Redis et bien d'autres. Mais dans cette section, nous examinons en détail le cache en mémoire et son fonctionnement dans .NET Core.

Cache en mémoire

Fondamentalement, le cache en mémoire est utilisé pour les applications légères et petites et cela fonctionnera bien dans ce domaine. Il stocke les données dans la mémoire du serveur côté application et les utilisateurs l'utilisent chaque fois que le besoin s'en fait sentir.

Avantages du cache en mémoire

  • Les utilisateurs récupèrent rapidement les données lorsque nous utilisons le cache en mémoire.
  • Cela augmentera les performances de l'application.
  • Idéal pour les petites applications déployées sur un seul serveur.

Inconvénients du cache en mémoire

  • Parfois, le cache en mémoire augmente la maintenance de l'application
  • Dans le cache en mémoire, les données sont conservées sur un seul serveur et si le serveur tombe en panne, les données sont perdues. Il est également difficile de faire évoluer l'application dans certains scénarios.

Nous allons maintenant créer une API .NET Core, y implémenter la mise en cache et comprendre comment les choses vont fonctionner.

Étape 1

Créer l'application Web de l'API .NET Core

Étape 2

Installez les packages NuGet suivants qui nécessitent étape par étape dans notre application

  • Microsoft.EntityFrameworkCoreMicrosoft.EntityFrameworkCore
  • Microsoft.EntityFrameworkCore.DesignMicrosoft.EntityFrameworkCore.Design
  • Microsoft.EntityFrameworkCore.SqlServerMicrosoft.EntityFrameworkCore.SqlServer
  • Microsoft.EntityFrameworkCore.Tools
  • Swashbuckle.AspNetCore
  • Système.Runtime.CachingSystem.Runtime.CachingSystem.Runtime.CachingSystem.Runtime.Caching

Étape 3

Créez le dossier Modèle et créez une classe de produits à l'intérieur avec des détails

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; }
    }
}

Étape 4

Ensuite, créez la classe DbContextClass pour les opérations liées à la base de données comme je l'ai montré ci-dessous

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;
        }
    }
}

Étape 5

Maintenant, nous allons créer l'interface ICacheService et la classe CacheService pour une utilisation liée au cache en mémoire.

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;
        }
    }
}

Étape 6

Créez la classe ProductController, créez la méthode suivante comme indiqué ci-dessous

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();
        }
    }
}

Étape 7

Ajoutez la chaîne de connexion SQL Server dans appsetting.json

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

Étape 8

Ensuite, enregistrez ICacheService dans la méthode Configure Service de Startup Class et ajoutez également une configuration liée à Swagger pour tester nos points de terminaison 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();
            });
        }
    }
}

Étape 9

Effectuez la migration et la mise à jour de la base de données pour la création de la base de données à l'aide des commandes suivantes dans la console du gestionnaire de packages.

add-migration "FirstMigration"

mise à jour de la base de données

Ainsi, lorsque vous entrez et exécutez cette commande, elle génère peu de choses liées à la migration et crée la base de données à l'intérieur de SQL Server comme vous l'avez mis à l'intérieur de la chaîne de connexion dans le appsetting.json

Étape 10

Enfin, exécutez l'application et ajoutez les données à l'aide de l'interface utilisateur swagger, puis vérifiez le fonctionnement de la mise en cache dans les produits et le point de terminaison du produit.

Fondamentalement, j'ai ajouté du cache dans les points de terminaison du produit et des produits dans le contrôleur, comme vous le voyez lorsque l'utilisateur veut récupérer les données de tous les produits, puis il vérifiera d'abord si les données sont présentes dans le cache en mémoire ou non et si c'est présent à l'intérieur du cache, puis renvoyez ces données à l'utilisateur et si les données ne sont pas présentes dans le cache, il récupérera les données de la base de données et les placera également dans le cache. Ainsi, la prochaine fois, l'utilisateur obtiendra cela uniquement à partir du cache et évitera d'accéder inutilement à la base de données 

De plus, lorsque l'utilisateur souhaite récupérer des données à l'aide de l'identifiant du produit, comme vous le voyez dans le contrôleur du deuxième point de terminaison du produit, nous récupérons les données du cache de tous les produits, puis les filtrons à l'aide de l'identifiant du produit et, si celui-ci est présent, revenons à l'utilisateur à partir du cache et si pas ensuite récupérer de la base de données et revenir à l'utilisateur après avoir appliqué le filtre.

Ainsi, comme vous le voyez à l'intérieur de la mise à jour, de la suppression et de la publication du point de terminaison du contrôleur de produit, nous utilisons la méthode de suppression pour supprimer les données de la clé de produit qui sont présentes dans le cache. Ainsi, il existe de nombreux scénarios et utilisations de caches mémoire que vous pouvez utiliser selon vos besoins et vos exigences. Je veux juste présenter les bases du cache mémoire et son fonctionnement à l'intérieur du .NET Core que j'ai couvert ici.

De plus, il y a un scénario dont vous devez vous occuper lors de l'utilisation de la mise en cache comme supposons, il y a deux utilisateurs qui utilisent votre application, alors les scénarios suivants viendront

  • Lorsque le premier utilisateur envoie la demande pour récupérer les données de tous les produits, la première demande arrive, puis il vérifiera si les données sont présentes dans le cache ou non et si les données sont présentes dans le cache, alors il récupérera les données de la base de données et définissez-le également dans le cache.
  • Pendant ce temps, le deuxième utilisateur envoie la demande pour obtenir les détails du produit, puis la demande accède également à la base de données avant de terminer la demande du premier utilisateur et, à cause de ce deuxième utilisateur, accède également à la base de données pour récupérer les détails du produit.
  • Donc, il existe une solution pour cela d'utiliser le mécanisme de verrouillage comme indiqué ci-dessous

Ajoutez créer un objet de verrouillage en haut de la classe puis dans la méthode comme je l'ai montré ci-dessous

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;
}

Donc, ici, comme vous le voyez d'abord, nous vérifions si les données sont présentes dans le cache ou non si les données sont disponibles, puis nous les renvoyons. Ensuite, si la valeur n'est pas présente dans le cache mémoire, nous appliquons le verrou là-bas, puis la demande est verrouillée et entrée dans la section et récupère les détails du produit dans la base de données, puis la définit également dans le cache, puis retourner les données. Ainsi, lorsque le deuxième utilisateur envoie une demande avant que la demande de l'utilisateur ne soit terminée. Ainsi, dans ce cas, la deuxième demande est dans la file d'attente et après avoir terminé la première demande de l'utilisateur, la deuxième demande entre en ligne de compte

Il s'agit du cache en mémoire dans .NET Core. J'espère que vous comprenez les choses liées à cela.

Bon codage !

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

  #aspdotnet #api #csharp #dotnet 

Implémenter Le Cache En Mémoire Dans L'API .NET Core
Coding  Fan

Coding Fan

1655699024

How to Create ASP.NET Web API Application Which Deals with a SQL Server Database

In this video we will create ASP.NET Web API application which deals with a SQL Server database. We will be using this application just to understand the ASP.NET Web API concepts and its most commonly used methods.
This tutorial will help you to understand the Web API Insert Update Delete methods in Asp.net WEB API with Sql Server.

Introduction To ASP .NET Web API :
The term API stands for Application Programming Interface. ASP.NET Web API is a framework for building Web API’s, i.e. HTTP based services on top of the .NET Framework. The most common use case for using Web API is for building RESTful services.

What are RESTful services :
REST stands for Representational State Transfer. REST was first introduced in the year 2000 by Roy Fielding as part of his doctoral dissertation. 
REST is an architectural pattern for creating an API that uses HTTP as its underlying communication method. The REST architectural pattern specifies a set of constraints that a system should adhere to.

Subscribe: https://www.youtube.com/c/ManojDeshwal/featured 

#aspdotnet #sqlserver   

How to Create ASP.NET Web API Application Which Deals with a SQL Server Database
Alexis Gilbert

Alexis Gilbert

1655371419

.Net core vs .Net framework performance: A comparative analysis.

#programmiing #webdev #dotnet #aspdotnet #dot 

This rivalry between .Net vs .Net core framework is nothing new in the web application development industry.

Anyone who is working in this industry can vouch for that pressure, the dilemma they have to make a choice between the old vs new.

Believe me, and I know the struggle when it comes to opting from old vs new, where you can't trust the newer version as it doesn't have that old trustworthiness, and the old option is, well, getting old!

The selection from both can be done based on various factors and attributes; However, in this blog, we are mainly doing this comparative analysis based on the .Net vs .Net core framework performance and checking out the factors affecting their performances at the time of building web applications.

If we talk about .Net, it is one of the best server-side open-source platforms. With .Net, you can utilize multiple languages, editors, and libraries to build desktop or IoT-based applications.

Whereas the .Net core is widely adopted as an answer to the limitations of the .Net

.Net Core is a cross-platform application that works with Windows, Linux, or macOS-based operating systems. 

The fascinating thing about this framework is that it has a solid open source community, so one can expect an extending hand if he is stuck at some point, somewhere.

If we carefully observe the ongoing trend between both versions, both walk on the same tracks, but lately, the .Net core has started growing in terms of popularity in the .Net community in recent times.

.Net core vs .Net framework performance

When numerous resources are on the stack, you are always stuck with the problem of which option would benefit your web applications? Since .Net 3.1 took over with its latest updated features, the performance has significantly increased throughout the years.

If we look at the entire situation here, the overall .Net core has reported excellent performance compared to its .Net. However, there have been minor performance regression errors have been reported in the community with the .Net core 3.1 version compared to .Net 4.8

When the GitHub performance test has been conducted, the test results came something like this, When the .Net core has been triggered, it is using more than 2x CPU speed time.

In another test.Net 4.8 has found rendering speed more than 10-20% than the .Net core application. The regression performance was noted merely a bit slower than the .Net 4.8 version.If we dig deeper into the details, observe this benchmark report of .Net core vs .Net framework performance based on experimental observations.

The compatible test:

.Net Core is quite famous for its compatibility with macOS, Windows and Linux models, and it can work with anything

On the other hand, .Net web development is quite comfortable with Windows operating system, and to cover such flexes, the architecture has been restructured to create the .Net core more convenient and extensive.

.Net framework is ideal to use for any organization when the deployment requirement is for long-term projects.

Microsoft has already shown they have no interest in forbidding such a robust framework .Net to put things together. However, they do intend to limit the new releases in order to limit their complexity.

For those who have already working on .Net, there is no such kind of urgency to migrate to .Net core.

But yes, if someone is entering into this industry and it is their beginning, they definitely have a prominent choice to make here.

Fortunately, there are few good options out there with an expert and skilled .Net and .Net core developer team who knows the Developing industry well especially working in mobile application developing or building progressive web applications.

If you feel like these things are a bit tricky and complex, you can always get the free consultation of a .Net Core Development Company that can optimize your resources while promising the best of class output for your project.

If you have liked this blog and are interested in reading more about it, this blog can be a treat for you!


 

EFコアとPostgresを使用した.NETコアのRESTfulAPI

REST API は、サーバーと通信するために複数のクライアント(またはAPPS)が使用できるアプリケーションプログラミングインターフェイスです。

Rest APIは、アプリケーションに必要なデータを便利な形式(JSONやXMLなど)で保存および取得する一種のWebサービスです。

ステートレスであるため、Webサービスにアクセスするために依存するコードライブラリを必要としないため、開発者に大きな柔軟性を提供します。

RESTでサポートされている多くのプロトコルの中で、最も一般的なものはHTTPです。

HTTPRequestを使用してクライアントから要求が送信されると、対応する応答がHTTPResponseを使用してサーバーから送信されます。リクエストとレスポンスでサポートされている最も広く使用されている機械可読形式は、JSON(Javascript Object Notification)とXML(Extensible Markup Language)です。

RESTは、コンピューター科学者のROYFIELDINGによって作成されました。

REST APIを使用して、さまざまなアクションを実行できます。アクションに基づいて、関連する方法を使用する必要があります。以下は、RESTでサポートされている5つの方法です。

  1. GET-このメソッドは、データベース/サーバーからデータを取得するために使用されます。
  2. POST-このメソッドは、新しいレコードを作成するために使用されます。
  3. PUT-このメソッドは、レコードを変更/置換するために使用されます。レコード全体を置き換えます。
  4. PATCH-このメソッドは、レコードを変更/更新するために使用されます。レコードの一部を置き換えます。
  5. DELETE-このメソッドは、レコードを削除するために使用されます。

EfCoreとPostgresを使用したdotnetCoreのRESTfulApi

これを例で見てみましょう。私たちは、母親が十分な休息をとることが決してないことを知っています。しかし、これらの休むことのないママを例として取り上げ、RestAPIをどのように使用するかを見てみましょう。:)

生まれたばかりの赤ちゃんによる過度の要求の中で、おむつはリーダーボードで最初に位置します。

母親は赤ちゃんのためにすべてが最善であることを望んでいます。ですから、母親が赤ちゃんに最適なおむつを選びたいと思うのは明らかです。そこで、彼女はショッピングWebサイト(フリップカートを想定)にアクセスして、おむつを検索します。これにより、すべてのおむつのリストを取得するために、フリップカートのサーバーにHTTPリクエストが送信されます。FlipkartのサーバーはHTTP応答で応答します。これは、いくつかの基本的な詳細を含むおむつのリストを含むJSONオブジェクト(想定)になります。FlipkartのWebサイトは、この応答を読み取り、人間が読める形式に変換して、母親が見ることができるようにWebページに表示します。

彼女が生まれたばかりの赤ちゃんのために特定のおむつを選び、それを彼女のリストに追加した後。これにより、POSTリクエストが作成され、おむつのブランド、サイズ、数量、価格などを含む新しいレコードがフリップカートのデータベースに作成されます。

彼女の赤ちゃんは成長を続け、すぐに新生児のサイズを超えます。母親がまだおむつのブランドを気に入っていて、サイズを大きくしたいとします。彼女がしなければならないのは、新しいおむつのサイズを選択することだけです。彼女がおむつのサイズを新生児のサイズからサイズ1に更新すると、これによりPATCHメソッドがトリガーされ、他のすべては同じままで、おむつのサイズのみが変更されます。

母親が現在のブランドを変更し、別のブランドに切り替えることを決定することは非常に一般的です。ここで、母親はPUTリクエストを開始します。ここで、以前に選択されたブランドを含むデータ全体が変更され、新しく選択されたブランドに対応するデータに置き換えられます。

最後に、いくつかのGET、POST、PUT、およびPATCHを含む一連の実験の後、母親が子供をトイレトレーニングする時が来ました。彼女が子供を訓練することに成功した場合、おむつはもはや必要ありません。これにより、 DELETE要求がトリガーされます。

前提条件

  1. Visual Studio 2022
  2. .Net Core 6:ASP.NET Coreは、Microsoftによって開発されたASP.NETの新しいバージョンです。これは、WebアプリケーションとAPIを開発するためのオープンソースフレームワークであり、Windows、Mac、またはLinuxで実行できます。Asp.Net Coreは、最新のクラウドベースのインターネット接続アプリケーションを構築するためのクロスプラットフォーム、高性能、オープンソースフレームワークです。
  3. Entity Frameworkコア:Entity Framework(EF)コアは、人気のあるEntityFrameworkデータアクセステクノロジの軽量で拡張可能な オープンソース のクロスプラットフォームバージョンです。
  4. Postgresデータベース:PostgreSQLは強力なオープンソースのオブジェクトリレーショナルデータベースシステムであり、30年以上にわたって活発に開発されており、信頼性、機能の堅牢性、パフォーマンスで高い評価を得ています。

API作成手順

ステップ1

Visual Studio 2022を開き、asp.netコアwebapiプロジェクトを作成します。

ステップ2

NugetからNpgsql.EntityFrameworkCore.PostgreSQLとMicrosoft.EntityFrameworkCore.Toolsをインストールします

ステップ3

Product.csとOrder.csを作成します

using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
[Table("product")]
public class Product {
    [Key, Required]
    public int id {
        get;
        set;
    }
    [Required]
    public string ? name {
        get;
        set;
    }
    public string ? brand {
        get;
        set;
    }
    public string ? size {
        get;
        set;
    }
    public decimal price {
        get;
        set;
    }
    public virtual ICollection < Order > orders {
        get;
        set;
    }
}
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
[Table("order")]
public class Order {
    [Key, Required]
    public int id {
        get;
        set;
    }
    public int product_id {
        get;
        set;
    }
    [Required]
    public string ? name {
        get;
        set;
    }
    public string ? address {
        get;
        set;
    }
    public string ? phone {
        get;
        set;
    }
    public DateTime createdon {
        get;
        set;
    }
    public virtual Product product {
        get;
        set;
    }
}

ステップ4

DbContextクラスから継承されたEF_DataContextを作成します 

using Microsoft.EntityFrameworkCore;
public class EF_DataContext: DbContext {
    public EF_DataContext(DbContextOptions < EF_DataContext > options): base(options) {}
    protected override void OnModelCreating(ModelBuilder modelBuilder) {
        modelBuilder.UseSerialColumns();
    }
    public DbSet <Product> Products {
        get;
        set;
    }
    public DbSet <Order> Orders {
        get;
        set;
    }
}

ステップ5

appsetting.jsonを開きます

"ConnectionStrings": {
    "Ef_Postgres_Db": "Server=localhost;Database=shopingpostgres;Port=5432;User Id=postgres;Password=qwerty1234;"
}

ステップ6

Program.csを開く

builder.Services.AddDbContext < EF_DataContext > (o => o.UseNpgsql(builder.Configuration.GetConnectionString("Ef_Postgres_Db")));

ステップ7

2つのコマンドを実行します 

Add-Migration InitialDatabase
Update-Database

ステップ8

API通信に使用されるAPI製品モデルと注文モデルを作成します

public class Product {
    public int id {
        get;
        set;
    }
    public string ? name {
        get;
        set;
    }
    public string ? brand {
        get;
        set;
    }
    public string ? size {
        get;
        set;
    }
    public decimal price {
        get;
        set;
    }
}
public class Order {
    public int id {
        get;
        set;
    }
    public int product_id {
        get;
        set;
    }
    public string ? name {
        get;
        set;
    }
    public string ? address {
        get;
        set;
    }
    public string ? phone {
        get;
        set;
    }
    public DateTime createdon {
        get;
        set;
    }
    public virtual Product product {
        get;
        set;
    }
}

ステップ9

データベースと通信するDBhelperクラスを追加します

using ShoppingWebApi.EfCore;
namespace ShoppingWebApi.Model {
    public class DbHelper {
        private EF_DataContext _context;
        public DbHelper(EF_DataContext context) {
            _context = context;
        }
        /// <summary>
        /// GET
        /// </summary>
        /// <returns></returns>
        public List < ProductModel > GetProducts() {
            List < ProductModel > response = new List < ProductModel > ();
            var dataList = _context.Products.ToList();
            dataList.ForEach(row => response.Add(new ProductModel() {
                brand = row.brand,
                    id = row.id,
                    name = row.name,
                    price = row.price,
                    size = row.size
            }));
            return response;
        }
        public ProductModel GetProductById(int id) {
            ProductModel response = new ProductModel();
            var row = _context.Products.Where(d => d.id.Equals(id)).FirstOrDefault();
            return new ProductModel() {
                brand = row.brand,
                    id = row.id,
                    name = row.name,
                    price = row.price,
                    size = row.size
            };
        }
        /// <summary>
        /// It serves the POST/PUT/PATCH
        /// </summary>
        public void SaveOrder(OrderModel orderModel) {
            Order dbTable = new Order();
            if (orderModel.id > 0) {
                //PUT
                dbTable = _context.Orders.Where(d => d.id.Equals(orderModel.id)).FirstOrDefault();
                if (dbTable != null) {
                    dbTable.phone = orderModel.phone;
                    dbTable.address = orderModel.address;
                }
            } else {
                //POST
                dbTable.phone = orderModel.phone;
                dbTable.address = orderModel.address;
                dbTable.name = orderModel.name;
                dbTable.Product = _context.Products.Where(f => f.id.Equals(orderModel.product_id)).FirstOrDefault();
                _context.Orders.Add(dbTable);
            }
            _context.SaveChanges();
        }
        /// <summary>
        /// DELETE
        /// </summary>
        /// <param name="id"></param>
        public void DeleteOrder(int id) {
            var order = _context.Orders.Where(d => d.id.Equals(id)).FirstOrDefault();
            if (order != null) {
                _context.Orders.Remove(order);
                _context.SaveChanges();
            }
        }
    }
}

ステップ10

Apiコントローラーを作成し、ShoppingRestApiという名前を付けます

using Microsoft.AspNetCore.Mvc;
using ShoppingWebApi.EfCore;
using ShoppingWebApi.Model;
// For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860
namespace ShoppingWebApi.Controllers {
    [ApiController]
    public class ShoppingApiController: ControllerBase {
        private readonly DbHelper _db;
        public ShoppingApiController(EF_DataContext eF_DataContext) {
            _db = new DbHelper(eF_DataContext);
        }
        // GET: api/<ShoppingApiController>
        [HttpGet]
        [Route("api/[controller]/GetProducts")]
        public IActionResult Get() {
            ResponseType type = ResponseType.Success;
            try {
                IEnumerable < ProductModel > data = _db.GetProducts();
                if (!data.Any()) {
                    type = ResponseType.NotFound;
                }
                return Ok(ResponseHandler.GetAppResponse(type, data));
            } catch (Exception ex) {
                return BadRequest(ResponseHandler.GetExceptionResponse(ex));
            }
        }
        // GET api/<ShoppingApiController>/5
        [HttpGet]
        [Route("api/[controller]/GetProductById/{id}")]
        public IActionResult Get(int id) {
            ResponseType type = ResponseType.Success;
            try {
                ProductModel data = _db.GetProductById(id);
                if (data == null) {
                    type = ResponseType.NotFound;
                }
                return Ok(ResponseHandler.GetAppResponse(type, data));
            } catch (Exception ex) {
                return BadRequest(ResponseHandler.GetExceptionResponse(ex));
            }
        }
        // POST api/<ShoppingApiController>
        [HttpPost]
        [Route("api/[controller]/SaveOrder")]
        public IActionResult Post([FromBody] OrderModel model) {
            try {
                ResponseType type = ResponseType.Success;
                _db.SaveOrder(model);
                return Ok(ResponseHandler.GetAppResponse(type, model));
            } catch (Exception ex) {
                return BadRequest(ResponseHandler.GetExceptionResponse(ex));
            }
        }
        // PUT api/<ShoppingApiController>/5
        [HttpPut]
        [Route("api/[controller]/UpdateOrder")]
        public IActionResult Put([FromBody] OrderModel model) {
            try {
                ResponseType type = ResponseType.Success;
                _db.SaveOrder(model);
                return Ok(ResponseHandler.GetAppResponse(type, model));
            } catch (Exception ex) {
                return BadRequest(ResponseHandler.GetExceptionResponse(ex));
            }
        }
        // DELETE api/<ShoppingApiController>/5
        [HttpDelete]
        [Route("api/[controller]/DeleteOrder/{id}")]
        public IActionResult Delete(int id) {
            try {
                ResponseType type = ResponseType.Success;
                _db.DeleteOrder(id);
                return Ok(ResponseHandler.GetAppResponse(type, "Delete Successfully"));
            } catch (Exception ex) {
                return BadRequest(ResponseHandler.GetExceptionResponse(ex));
            }
        }
    }
}

ステップ11

API応答を処理する応答モデルと応答ハンドラーを追加します

namespace ShoppingWebApi.Model {
    public class ApiResponse {
        public string Code {
            get;
            set;
        }
        public string Message {
            get;
            set;
        }
        public object ? ResponseData {
            get;
            set;
        }
    }
    public enum ResponseType {
        Success,
        NotFound,
        Failure
    }
}

次に、ビデオで示されているように、POSTMANを使用してAPIをテストします。

このストーリーは、もともとhttps://www.c-sharpcorner.com/article/restful-api-in-net-core-using-ef-core-and-postgres/で公開されました

#restful #api #aspdotnet #postgre #efcore 

EFコアとPostgresを使用した.NETコアのRESTfulAPI

API Restful en .NET Core usando EF Core y Postgres

REST API  es una interfaz de programación de aplicaciones que pueden utilizar varios clientes (o APLICACIONES) para comunicarse con un servidor.

Rest API es un tipo de servicio web que almacena y recupera los datos necesarios para su aplicación en un formato conveniente (por ejemplo, JSON o XML).

Proporciona una gran flexibilidad a los desarrolladores, ya que no necesita ninguna biblioteca de código dependiente para acceder a los servicios web, ya que no tiene estado.

Entre los muchos protocolos admitidos por REST, el más común es HTTP .

Cuando se envía una solicitud desde el cliente mediante HTTPRequest , se envía una respuesta correspondiente desde el servidor mediante HTTPResponse . Los formatos legibles por máquina más utilizados y admitidos para solicitudes y respuestas son JSON (Notificación de objetos Javascript) y XML (Lenguaje de marcado extensible).

REST fue creado por el informático ROY FIELDING .

Las API REST se pueden usar para realizar diferentes acciones. En función de las acciones, se debe utilizar el método pertinente. Los siguientes son los 5 métodos compatibles con REST.

  1. GET: este método se utiliza para recuperar datos de la base de datos/servidor.
  2. POST: este método se utiliza para crear un nuevo registro.
  3. PUT - Este método se utiliza para modificar/reemplazar el registro. Reemplaza todo el registro.
  4. PATCH - Este método se utiliza para modificar/actualizar el registro. Reemplaza partes del registro.
  5. ELIMINAR: este método se utiliza para eliminar el registro.

Restful Api en dotnet Core usando Ef Core y Postgres

Veamos esto con un ejemplo. Sabemos que las madres nunca descansan lo suficiente. Pero tomemos estas mamás sin descanso como ejemplo y veamos cómo usan Rest API. :)

Entre las demandas excesivas de un bebé recién nacido, el cambio de pañales ocupa el primer lugar en la tabla de clasificación.

Una madre quiere todo lo mejor para el bebé. Entonces, es obvio que la madre querría elegir el mejor pañal para su bebé. Entonces, ella va a un sitio web de compras (supongamos: flipkart) y busca pañales. Esto enviará una solicitud HTTP al servidor de flipkart para OBTENER la lista de todos los pañales. El servidor de Flipkart responde con una respuesta HTTP que será un objeto JSON (supongamos) que contiene una lista de pañales con algunos detalles básicos. El sitio web de Flipkart lee esta Respuesta, la convierte a un formato legible por humanos y la muestra en la página web para que la madre la vea.

Después, elige un pañal en particular para su bebé recién nacido y lo agrega a su lista. Esto crea una solicitud POST donde se crea un nuevo registro en la base de datos de flipkart que contiene la marca, el tamaño, la cantidad, el precio, etc. del pañal.

Su bebé sigue creciendo y pronto supera el tamaño del recién nacido. Supongamos que a la madre todavía le gusta la marca de pañales y solo quiere aumentar su tamaño, todo lo que tiene que hacer es elegir el nuevo tamaño de pañal. Cuando actualiza el tamaño del pañal del tamaño recién nacido al tamaño 1, se activa un método PATCH donde todo lo demás permanece igual y solo se cambia el tamaño del pañal.

Es muy común que la madre cambie la marca actual y decida cambiar a una alternativa. Aquí, la madre iniciará una solicitud PUT donde todos los datos que contienen la marca elegida previamente se modifican y reemplazan con los datos correspondientes a la marca recién elegida.

Finalmente, después de una serie de experimentos que involucran varios GET, POST, PUT y PATCH, es hora de que la madre enseñe al niño a ir al baño. Si logra entrenar al niño, ya no necesitará los pañales. Esto activa una solicitud DELETE .

PRERREQUISITOS

  1. estudio visual 2022
  2. .Net Core 6: ASP.NET Core es una nueva versión de ASP.NET, desarrollada por Microsoft. Es un marco de código abierto para desarrollar aplicaciones web y API y se puede ejecutar en Windows, Mac o Linux. Asp.Net Core es un marco de código abierto, multiplataforma y de alto rendimiento para crear aplicaciones modernas, basadas en la nube y conectadas a Internet.
  3. Núcleo de Entity Framework: Entity Framework (EF) Core es una versión liviana, extensible,  de código abierto  y multiplataforma de la popular tecnología de acceso a datos de Entity Framework.
  4. Base de datos de Postgres: PostgreSQL es un poderoso sistema de base de datos relacional de objetos de código abierto con más de 30 años de desarrollo activo que le ha valido una sólida reputación por su confiabilidad, robustez de funciones y rendimiento.

PASOS DE CREACIÓN DE API

Paso 1

Abra Visual Studio 2022 y cree el proyecto asp.net core webapi.

Paso 2

Instale Npgsql.EntityFrameworkCore.PostgreSQL y Microsoft.EntityFrameworkCore.Tools desde Nuget

Paso 3

Crear Product.cs y Order.cs

using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
[Table("product")]
public class Product {
    [Key, Required]
    public int id {
        get;
        set;
    }
    [Required]
    public string ? name {
        get;
        set;
    }
    public string ? brand {
        get;
        set;
    }
    public string ? size {
        get;
        set;
    }
    public decimal price {
        get;
        set;
    }
    public virtual ICollection < Order > orders {
        get;
        set;
    }
}
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
[Table("order")]
public class Order {
    [Key, Required]
    public int id {
        get;
        set;
    }
    public int product_id {
        get;
        set;
    }
    [Required]
    public string ? name {
        get;
        set;
    }
    public string ? address {
        get;
        set;
    }
    public string ? phone {
        get;
        set;
    }
    public DateTime createdon {
        get;
        set;
    }
    public virtual Product product {
        get;
        set;
    }
}

Paso 4

Crear EF_DataContext heredado de la clase DbContext 

using Microsoft.EntityFrameworkCore;
public class EF_DataContext: DbContext {
    public EF_DataContext(DbContextOptions < EF_DataContext > options): base(options) {}
    protected override void OnModelCreating(ModelBuilder modelBuilder) {
        modelBuilder.UseSerialColumns();
    }
    public DbSet <Product> Products {
        get;
        set;
    }
    public DbSet <Order> Orders {
        get;
        set;
    }
}

Paso 5

Abrir appsetting.json

"ConnectionStrings": {
    "Ef_Postgres_Db": "Server=localhost;Database=shopingpostgres;Port=5432;User Id=postgres;Password=qwerty1234;"
}

Paso 6

Abrir programa.cs

builder.Services.AddDbContext < EF_DataContext > (o => o.UseNpgsql(builder.Configuration.GetConnectionString("Ef_Postgres_Db")));

Paso 7

Ejecuta los 2 comandos 

Add-Migration InitialDatabase
Update-Database

Paso 8

Cree los modelos de pedido y producto API que se utilizarán para la comunicación API

public class Product {
    public int id {
        get;
        set;
    }
    public string ? name {
        get;
        set;
    }
    public string ? brand {
        get;
        set;
    }
    public string ? size {
        get;
        set;
    }
    public decimal price {
        get;
        set;
    }
}
public class Order {
    public int id {
        get;
        set;
    }
    public int product_id {
        get;
        set;
    }
    public string ? name {
        get;
        set;
    }
    public string ? address {
        get;
        set;
    }
    public string ? phone {
        get;
        set;
    }
    public DateTime createdon {
        get;
        set;
    }
    public virtual Product product {
        get;
        set;
    }
}

Paso 9

Agregue la clase DBhelper que hablará con su base de datos

using ShoppingWebApi.EfCore;
namespace ShoppingWebApi.Model {
    public class DbHelper {
        private EF_DataContext _context;
        public DbHelper(EF_DataContext context) {
            _context = context;
        }
        /// <summary>
        /// GET
        /// </summary>
        /// <returns></returns>
        public List < ProductModel > GetProducts() {
            List < ProductModel > response = new List < ProductModel > ();
            var dataList = _context.Products.ToList();
            dataList.ForEach(row => response.Add(new ProductModel() {
                brand = row.brand,
                    id = row.id,
                    name = row.name,
                    price = row.price,
                    size = row.size
            }));
            return response;
        }
        public ProductModel GetProductById(int id) {
            ProductModel response = new ProductModel();
            var row = _context.Products.Where(d => d.id.Equals(id)).FirstOrDefault();
            return new ProductModel() {
                brand = row.brand,
                    id = row.id,
                    name = row.name,
                    price = row.price,
                    size = row.size
            };
        }
        /// <summary>
        /// It serves the POST/PUT/PATCH
        /// </summary>
        public void SaveOrder(OrderModel orderModel) {
            Order dbTable = new Order();
            if (orderModel.id > 0) {
                //PUT
                dbTable = _context.Orders.Where(d => d.id.Equals(orderModel.id)).FirstOrDefault();
                if (dbTable != null) {
                    dbTable.phone = orderModel.phone;
                    dbTable.address = orderModel.address;
                }
            } else {
                //POST
                dbTable.phone = orderModel.phone;
                dbTable.address = orderModel.address;
                dbTable.name = orderModel.name;
                dbTable.Product = _context.Products.Where(f => f.id.Equals(orderModel.product_id)).FirstOrDefault();
                _context.Orders.Add(dbTable);
            }
            _context.SaveChanges();
        }
        /// <summary>
        /// DELETE
        /// </summary>
        /// <param name="id"></param>
        public void DeleteOrder(int id) {
            var order = _context.Orders.Where(d => d.id.Equals(id)).FirstOrDefault();
            if (order != null) {
                _context.Orders.Remove(order);
                _context.SaveChanges();
            }
        }
    }
}

Paso 10

Cree su controlador Api, asígnele el nombre ShoppingRestApi

using Microsoft.AspNetCore.Mvc;
using ShoppingWebApi.EfCore;
using ShoppingWebApi.Model;
// For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860
namespace ShoppingWebApi.Controllers {
    [ApiController]
    public class ShoppingApiController: ControllerBase {
        private readonly DbHelper _db;
        public ShoppingApiController(EF_DataContext eF_DataContext) {
            _db = new DbHelper(eF_DataContext);
        }
        // GET: api/<ShoppingApiController>
        [HttpGet]
        [Route("api/[controller]/GetProducts")]
        public IActionResult Get() {
            ResponseType type = ResponseType.Success;
            try {
                IEnumerable < ProductModel > data = _db.GetProducts();
                if (!data.Any()) {
                    type = ResponseType.NotFound;
                }
                return Ok(ResponseHandler.GetAppResponse(type, data));
            } catch (Exception ex) {
                return BadRequest(ResponseHandler.GetExceptionResponse(ex));
            }
        }
        // GET api/<ShoppingApiController>/5
        [HttpGet]
        [Route("api/[controller]/GetProductById/{id}")]
        public IActionResult Get(int id) {
            ResponseType type = ResponseType.Success;
            try {
                ProductModel data = _db.GetProductById(id);
                if (data == null) {
                    type = ResponseType.NotFound;
                }
                return Ok(ResponseHandler.GetAppResponse(type, data));
            } catch (Exception ex) {
                return BadRequest(ResponseHandler.GetExceptionResponse(ex));
            }
        }
        // POST api/<ShoppingApiController>
        [HttpPost]
        [Route("api/[controller]/SaveOrder")]
        public IActionResult Post([FromBody] OrderModel model) {
            try {
                ResponseType type = ResponseType.Success;
                _db.SaveOrder(model);
                return Ok(ResponseHandler.GetAppResponse(type, model));
            } catch (Exception ex) {
                return BadRequest(ResponseHandler.GetExceptionResponse(ex));
            }
        }
        // PUT api/<ShoppingApiController>/5
        [HttpPut]
        [Route("api/[controller]/UpdateOrder")]
        public IActionResult Put([FromBody] OrderModel model) {
            try {
                ResponseType type = ResponseType.Success;
                _db.SaveOrder(model);
                return Ok(ResponseHandler.GetAppResponse(type, model));
            } catch (Exception ex) {
                return BadRequest(ResponseHandler.GetExceptionResponse(ex));
            }
        }
        // DELETE api/<ShoppingApiController>/5
        [HttpDelete]
        [Route("api/[controller]/DeleteOrder/{id}")]
        public IActionResult Delete(int id) {
            try {
                ResponseType type = ResponseType.Success;
                _db.DeleteOrder(id);
                return Ok(ResponseHandler.GetAppResponse(type, "Delete Successfully"));
            } catch (Exception ex) {
                return BadRequest(ResponseHandler.GetExceptionResponse(ex));
            }
        }
    }
}

Paso 11

Agregue el modelo de respuesta y el controlador de respuesta que manejará sus respuestas API

namespace ShoppingWebApi.Model {
    public class ApiResponse {
        public string Code {
            get;
            set;
        }
        public string Message {
            get;
            set;
        }
        public object ? ResponseData {
            get;
            set;
        }
    }
    public enum ResponseType {
        Success,
        NotFound,
        Failure
    }
}

Ahora pruebe las API usando POSTMAN como se muestra en el video.

Esta historia se publicó originalmente en https://www.c-sharpcorner.com/article/restful-api-in-net-core-using-ef-core-and-postgres/

#restful #api #aspdotnet #postgre #efcore 

API Restful en .NET Core usando EF Core y Postgres
坂本  篤司

坂本 篤司

1654318800

ASP.NETCore6プロジェクトにStartup.csクラスを追加する方法

ここでは、ASP.NET 6.0プロジェクトで作業しているときに、Asp.netコアアプリケーションにstartup.csファイルを追加する方法を学習します。それでは始めましょう。

6.0でasp.netコアアプリケーションを作成している場合、以前のバージョンのasp.netコアアプリケーションで見たように、プロジェクトファイルにStartup.csクラスは表示されず、依存関係を登録していました。アプリケーションとミドルウェアの

そのため、ASP.NET 6.0では、Startup.csクラスが削除され、Program.csクラスがアプリケーションとミドルウェアの依存関係を登録する場所になります。

ただし、ミドルウェアと依存関係をスタートアップクラスに記述したい場合は、ここでASP.NET6.0プロジェクトにstartup.csクラスを追加する方法を学習します。

以下は、ASP.NET6.0プロジェクトに存在するProgram.csファイルです。

var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddRazorPages();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment()) {
    app.UseExceptionHandler("/Error");
    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
    app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapRazorPages();
app.Run();

上記のコードを見るとわかるように、ミドルウェアとサービスはProgram.csクラスで記述されています。ご存知 のとおりStartup.cs 、2つのメソッドが含まれ てConfigureServices() おり Configure() 、依存関係とサービスをメソッドに登録し ConfigureServices() 、ミドルウェアを Configure() メソッドに登録します。

現在、asp.net 6.0では 、は、の後にサービスと依存関係を登録し、の後 にミドルウェア Program.csを登録する必要がある場所です。builder.Services.AddRazorPages();var app = builder.Build();


ミドルウェアをパイプラインに登録するときは、順序が重要です。

ここ Startup.cs で、ASP.NET Core 6.0プロジェクトに追加するには、  Startup.csという名前の新しいクラス を追加し、次のコードを追加します。

public class Startup {
    public IConfiguration configRoot {
        get;
    }
    public Startup(IConfiguration configuration) {
        configRoot = configuration;
    }
    public void ConfigureServices(IServiceCollection services) {
        services.AddRazorPages();
    }
    public void Configure(WebApplication app, IWebHostEnvironment env) {
        if (!app.Environment.IsDevelopment()) {
            app.UseExceptionHandler("/Error");
            // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
            app.UseHsts();
        }
        app.UseHttpsRedirection();
        app.UseStaticFiles();
        app.UseRouting();
        app.UseAuthorization();
        app.MapRazorPages();
        app.Run();
    }
}

したがって、上記のコードでは、以前のバージョンのasp.netで使用していたように、スタートアップクラスを追加し、ConfigureServicesとConfigureの2つのメソッドを追加したことがわかります。

上記のファイルを追加した後、program.csクラスから依存関係とサービスのコードを削除し、そのコードをConfigureServices()メソッドに入れ、Configureメソッドの同じミドルウェアコードを入れて、program.csクラスから削除します。

Program.csクラスとStartup.csクラスを更新した後、以下のようにprogram.csクラスからstartup.csクラスを呼び出す必要があります。

var builder = WebApplication.CreateBuilder(args);
var startup = new Startup(builder.Configuration);
startup.ConfigureServices(builder.Services); // calling ConfigureServices method
var app = builder.Build();
startup.Configure(app, builder.Environment); // calling Configure method

これで、アプリケーションを実行すると、エラーなしで実行されるはずです。 

上記のコードでは、Program.csクラスからstartup.csクラスメソッド(ConfigureServices、Configure)を呼び出していることがわかります。そのため、以前のバージョンのasp.netで行っていたように、メソッド名をConfigureServicesおよびConfigureメソッドとして記述する必要はありません。

以前はstartup.csメソッド名を変更することはできませんでしたが、今では必要に応じてメソッド名を記述し、これらのメソッドにそれぞれのコードを記述して、program.csクラスから同じものを呼び出すことができます。

このストーリーは、もともとhttps://www.c-sharpcorner.com/article/how-to-add-startup-cs-class-in-asp-net-core-6-project/で公開されました

#aspdotnet 

ASP.NETCore6プロジェクトにStartup.csクラスを追加する方法