Redis - artemovsergey/ASP GitHub Wiki

Controller with Redis

[ApiVersion("1.0")]
[ApiController]
[Route("api/v{version:apiVersion}/[controller]")]
public class UsersController : ControllerBase
{
    private readonly IUserService _userService;
    private readonly IMemoryCache _memoryCache;
    private readonly ApplicationContext _db;
    private readonly IDistributedCache _distributedCache;

    public UsersController(IUserService userService,
                           IMemoryCache memoryCache,
                           ApplicationContext db,
                           IDistributedCache distributedCache)
    {
        _userService = userService;
        _memoryCache = memoryCache;
        _db = db;
        _distributedCache = distributedCache;
    }

    [HttpPost]
    public IActionResult PostUser([FromBody] ApplicationUser user)
    {
        try
        {
            _db.Users.Add(user);
            _db.SaveChanges();
            return Ok(user);
        }
        catch (Exception e)
        {
            return BadRequest($"Bad Request: {e.InnerException.Message}");
            throw;
           
        }
    }

    [AspCore.Authorize]
    [HttpPost]
    [Route("login")]
    public async Task<ActionResult> LoginUser(ApplicationUser user)
    {
        var result = await _db.Users.Where(u => u.Email == user.Email).FirstOrDefaultAsync();
        if (result != null)
        {
            return Ok(result.Id);
        }
        else
        {
            return NotFound("Неправильный email или password");
        }
    }

    [HttpPost("auth")]
    public IActionResult Authenticate([FromBody] AuthenticateRequest model)
    {
        Console.WriteLine("Метод контроллера Authenticate");
        var response = _userService.Authenticate(model);
        
        if (response == null)
            return BadRequest(new { message = "Username or password is incorrect" });
        return Ok(response);
    }

    /*
     Кэширование в памяти не рекомендуется использовать 
     при работе нескольких экземпляров одного решения,
     поскольку данные не будут согласованы.
     */
    
    [HttpGet("{cakeName}")]
    public async Task<ApplicationUser> Get(string cakeName)
    {
        var cacheKey = cakeName.ToLower();
        if (!_memoryCache.TryGetValue(cacheKey, out ApplicationUser cakeList))
        {
            cakeList = _userService.GetById(1);
            var cacheExpirationOptions = new MemoryCacheEntryOptions
            {
                AbsoluteExpiration = DateTime.Now.AddHours(6),
                Priority = CacheItemPriority.Normal, SlidingExpiration = TimeSpan.FromMinutes(5)
            };
            _memoryCache.Set(cacheKey, cakeList, cacheExpirationOptions);
        }

        return cakeList;
    }

    [HttpGet]
    public async Task<ActionResult<IEnumerable<ApplicationUser>>> GetUsers(CancellationToken cancellationToken)
    {
        const string cacheKey = "GetUsers";
        IEnumerable<ApplicationUser> users;
        var cacheUsers = await _distributedCache.GetAsync(cacheKey, cancellationToken);

        if (cacheUsers == null)
        {
            users = _db.Users.ToList();
            var serializedUsers = JsonConvert.SerializeObject(users);
            cacheUsers = Encoding.UTF8.GetBytes(serializedUsers);

            var options = new DistributedCacheEntryOptions()
                .SetAbsoluteExpiration(DateTime.Now.AddMinutes(5))
                .SetSlidingExpiration(TimeSpan.FromMinutes(1));
            
            await _distributedCache.SetAsync(cacheKey,cacheUsers, options, cancellationToken);
            return Ok(users);
        }
        
        var result  = Encoding.UTF8.GetString(cacheUsers);
        users = JsonConvert.DeserializeObject<IEnumerable<ApplicationUser>>(result);
        return Ok(users);
    }
}