首页 > 解决方案 > 如何在 Blazor Server 项目中使用 SQL Server 和使用 .NET 5 的 EF Core 发出的每个请求中获取当前用户名?

问题描述

方法

我对我编写的服务使用依赖注入来获取当前用户名ApplicationDbContext

这是服务:

using System;
using Common;
using Microsoft.AspNetCore.Http;

namespace DataAccess.Service
{
    public class UserResolverService : IUserResolverService
    {
        private readonly IHttpContextAccessor _accessor;

        public UserResolverService(IHttpContextAccessor accessor)
        {
            _accessor = accessor;
        }

        public string GetCurrentUserName()
        {
           return _accessor?.HttpContext?.User?.Identity?.Name;
        }
    }
}

我已将容器中的服务注册为Transient服务:

services.AddHttpContextAccessor();
services.TryAddTransient<IUserResolverService, UserResolverService>();

使用依赖注入,我打算在任何模型状态更改时获取当前用户名和时间戳,例如Added// ModifiedDeleted以下是我ApplicationDbContextOnBeforeSaving意图。

using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Common;
using DataAccess.Service;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;

namespace DataAccess.Data
{
    public class ApplicationDbContext : IdentityDbContext<IdentityUser>
    {
        private readonly string _currentUserName;
        private readonly IUserResolverService _userResolverService;

        public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options, IUserResolverService userResolverService) : base(options)
        {
            _userResolverService = userResolverService;
            _currentUserName = _userResolverService.GetCurrentUserName();   
        }

        public override int SaveChanges(bool acceptAllChangesOnSuccess)
        {
            OnBeforeSaving(_currentUserName);
            return base.SaveChanges(acceptAllChangesOnSuccess);
        }

        public override Task<int> SaveChangesAsync(bool acceptAllChangesOnSuccess, CancellationToken cancellationToken = default(CancellationToken))
        {
            OnBeforeSaving(_currentUserName);
            return base.SaveChangesAsync(acceptAllChangesOnSuccess, cancellationToken);
        }

        public void OnBeforeSaving(string currentUserName)
        {
            string userName = String.IsNullOrEmpty(_currentUserName) ? SD.Role_Admin : _currentUserName;
            var entries = ChangeTracker
            .Entries()
            .Where(e =>
                    e.State == EntityState.Added
                    || e.State == EntityState.Modified || e.State == EntityState.Deleted);

            foreach (var entityEntry in entries)
            {
                try
                {
                    switch (entityEntry.State)
                    {
                        case EntityState.Added:
                            entityEntry.Property("CreatedDate").CurrentValue = DateTime.UtcNow;
                            entityEntry.Property("UpdatedDate").CurrentValue = DateTime.UtcNow;
                            entityEntry.Property("CreatedBy").CurrentValue = userName;
                            break;
                        case EntityState.Modified:
                            entityEntry.Property("UpdatedDate").CurrentValue = DateTime.UtcNow;
                            entityEntry.Property("UpdatedBy").CurrentValue = userName;
                            break;
                        case EntityState.Deleted:
                            entityEntry.Property("DeletedBy").CurrentValue = userName;
                            entityEntry.Property("DeletedDate").CurrentValue = DateTime.UtcNow;
                            break;

                    }
                }
                catch(Exception e)
                {
                }
            }
        }

        public DbSet<HotelRoom> HotelRooms { get; set; }
        public DbSet<HotelRoomImage> HotelRoomImages { get; set; }
        public DbSet<HotelAmenity> HotelAmenities { get; set; }
        public DbSet<ApplicationUser> ApplicationUser { get; set; }
        public DbSet<AdminUser> AdminUser { get; set; }
        public DbSet<RoomOrderDetails> RoomOrderDetails { get; set; }
    }
}

问题

ApplicationDbContext如果在 HTTP 请求中多次使用,我将无法在第一次之后捕获用户名。被CreatedBy正确捕获,UpdatedBy正在变空。

DeletedBy的意图DeletedAt是实现软删除。现在,即使在我的OnBeforeSaving函数之后,模型对象也会从数据库中删除。我相信我必须重写一些额外的方法。或者是否有任何配置可以让我做同样的事情?

我是 Blazor 的新手,任何帮助将不胜感激。

标签: c#.netasp.net-coreblazorblazor-server-side

解决方案


推荐阅读