C# 如何在ApplicationUser中设置数据?

C# 如何在ApplicationUser中设置数据?,c#,asp.net-mvc,C#,Asp.net Mvc,MyApplicationUser使用虚拟的UserData类进行扩展,例如 public partial class ApplicationUser : IdentityUser { [IgnoreDataMember, NotMapped] public IEnumerable<UserData> UserData { get; set; } } 这样,UserData就可以在我的控制器上进行依赖注入了? (为了演示,我已在上面的用户变量中设置了数据) 不幸的是,通过i

My
ApplicationUser
使用虚拟的
UserData
类进行扩展,例如

public partial class ApplicationUser : IdentityUser
{
  [IgnoreDataMember, NotMapped]
  public IEnumerable<UserData> UserData { get; set; }
}
这样,
UserData
就可以在我的控制器上进行依赖注入了? (为了演示,我已在上面的用户变量中设置了数据)


不幸的是,通过
identity.AddClaim
设置
UserData
不是一个选项,不建议在session中设置这样的值

在我的项目中,我喜欢做的是有一个单独的
SessionService
(您可以随意调用它)这是一个范围服务,其中存储了所有与用户相关的参数和可配置信息(例如他/她的访问级别、首选语言、角色、文化首选项、国籍、货币等)

为了初始化该服务,我使用了一个动作过滤器,这就是一个例子。要了解有关ASP.NETCore中过滤器的更多信息,您可以联系他们的

通过这种方式,由于ASP中的依赖项注入机制,您可以将有关用户的数据传递到应用程序中的每一层

您可以尝试这样做:

公共异步任务登录(字符串用户名,int-id)
{
//按用户名获取
ApplicationUser user=UserManager.FindByName(用户名);
//按用户id获取
ApplicationUser user=db.Users.Find(id);
//获取当前用户
ApplicationUser user=System.Web.HttpContext.Current.GetOwinContext()
.GetUserManager().FindById(转换)
.ToInt32(System.Web.HttpContext.Current.User.Identity.GetUserId());
//以及其他一些有用的方法
if(user==null)
{
//创建用户
user=newapplicationuser();
//填写用户属性
user.UserName=“约翰尼”;
user.Name=“约翰尼英语”;
//...
var result=UserManager.Create(用户);
//设置默认用户组和角色
var defaultGroup=“xxxx yyyy zz tttt”;//应用程序组的Id
SetUserGroups(user.Id,新字符串[]{defaultGroup});
groupManager.SetGroupRoles(newGroup.Id,新字符串[]{role.Name});
}
}

希望这有帮助。

您可以创建一个
ICurrentUserData
界面,并在实现中从您的上下文中获取用户数据

public interface ICurrentUserData
{
    public IEnumerable<UserData> UserData { get; }

}

public class CurrentUserData : ICurrentUserData
{
    private readonly IHttpContextAccessor _httpContextAccessor;
    private readonly myContext _context;
    private readonly UserManager<IdentityUser> _userManager;

    public CurrentUserData(myContext context, UserManager<ApplicationUser> userManager, IHttpContextAccessor httpContextAccessor)
    {
        _context = context;
        _userManager = userManager;
        _httpContextAccessor = httpContextAccessor;
    }

    private List<UserData> _userData;

    public IEnumerable<UserData> UserData 
    {
        get
        {
            if (_userData == null)
            {
                using (myContext myContext = new myContext())
                {
                    _userData = myContext.UserData.Where(x => x.UserId == _userManager.GetUserId(_httpContextAccessor.HttpContext.User)).ToList();
                }

            }
            return _userData;
        }
    }
}
公共接口ICurrentUserData
{
公共IEnumerable用户数据{get;}
}
公共类CurrentUserData:ICurrentUserData
{
专用只读IHttpContextAccessor\u httpContextAccessor;
私有只读myContext\u上下文;
私有只读用户管理器_UserManager;
公共CurrentUserData(myContext上下文、UserManager UserManager、IHttpContextAccessor httpContextAccessor)
{
_上下文=上下文;
_userManager=userManager;
_httpContextAccessor=httpContextAccessor;
}
私有列表\u用户数据;
公共IEnumerable用户数据
{
得到
{
如果(_userData==null)
{
使用(myContext myContext=new myContext())
{
_userData=myContext.userData.Where(x=>x.UserId==\u userManager.GetUserId(\u httpContextAccessor.HttpContext.User)).ToList();
}
}
返回用户数据;
}
}
}
您应该在启动时将它们注册为作用域,以便每个请求获得一个用户数据

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddScoped<ICurrentUserData, CurrentUserData>();
        services.AddHttpContextAccessor();
    }
}
公共类启动
{
public void配置服务(IServiceCollection服务)
{
services.addScope();
AddHttpContextAccessor();
}
}

在每次控制器执行之前和之后是否未应用操作筛选器?你看,我希望阅读数据,我认为你应该考虑这一部分。如果您只读取一次数据,那么如果数据在内部发生更改,您如何更新它。例如,管理员删除用户,阻止他/她,重置他的密码,等等。。。每个控制器操作之前都会应用操作过滤器,因此很容易维护和验证数据完整性。还有一件事需要考虑的是,当成百上千万的人同时开始使用该应用程序时会发生什么。你好,托尼,感谢你的努力。您提到的所有这些数据都驻留在ApplicationUser类中,因此此类管理更改不会成为问题。userData类是关于两个或三个属性的。在本例中,解决该问题的另一个方法是将该信息存储在缓存中。根据需要,可以使用各种类型的缓存。因此,通常相对于每个用户的标识符,您可以存储该信息,并在必要时读取该信息。这种逻辑同样可以在一个服务中分离出来,应该在需要的地方注入。你尝试过应用我的答案吗?@MuratYıldız answer似乎是correct@OrElse您甚至想做什么,您不能将IQuerable设置为您的userData
user.userData=myContext.userData.Where(x=>x.UserId==user.Id)
@johnny5谢谢johnny5。我还通过添加一些有用的方法和解释来编辑我的答案,这些方法和解释已经在使用
ASP.NET Identity
的一些项目中进行了测试和应用。@MuratYıldız您好,我还没有尝试过,我会说实话。事实上,我不太明白你的回答与我的问题有什么关系
    public class SessionProvider : ISessionProvider
    {
        public SessionProvider()
        {
            this.PreferredLanguage = string.Empty;
        }

        public bool AllowReconfiguration { get; private set; }
        public bool IsConfigured { get; private set; }
        public Guid UserId { get; private set; }
        public string PreferredLanguage { get; private set; }

        public void ConfigureSession(Guid userId, string preferredLanguage, bool allowReconfiguration = false)
        {
            if (this.AllowReconfiguration == false && this.IsConfigured) throw new InvalidOperationException(ErrorMessages.SessionCannotBeReconfigured);

            this.UserId = userId;
            this.PreferredLanguage = preferredLanguage;

            this.IsConfigured = true;
            this.AllowReconfiguration = allowReconfiguration;
        }
    }
public async Task<ActionResult> Login(string username, int id)
{
    // get by username
    ApplicationUser user = UserManager.FindByName(username);

    // get by user id
    ApplicationUser user = db.Users.Find(id);

    // get current user
    ApplicationUser user = System.Web.HttpContext.Current.GetOwinContext()
        .GetUserManager<ApplicationUserManager>().FindById(Convert
        .ToInt32(System.Web.HttpContext.Current.User.Identity.GetUserId()));

    // and some other useful methods        
    if (user == null)
    {
        // creating user 
        user = new ApplicationUser();

        // fill in the user properties 
        user.UserName = "johnny";
        user.Name = "Johnny English";
        //...
        var result = UserManager.Create(user);

        // set default user group and roles
        var defaultGroup = "xxxx-yyyy-zzzz-tttt"; // Id of the ApplicationGroup
        groupManager.SetUserGroups(user.Id, new string[] { defaultGroup });
        groupManager.SetGroupRoles(newGroup.Id, new string[] { role.Name });
    }
}
public interface ICurrentUserData
{
    public IEnumerable<UserData> UserData { get; }

}

public class CurrentUserData : ICurrentUserData
{
    private readonly IHttpContextAccessor _httpContextAccessor;
    private readonly myContext _context;
    private readonly UserManager<IdentityUser> _userManager;

    public CurrentUserData(myContext context, UserManager<ApplicationUser> userManager, IHttpContextAccessor httpContextAccessor)
    {
        _context = context;
        _userManager = userManager;
        _httpContextAccessor = httpContextAccessor;
    }

    private List<UserData> _userData;

    public IEnumerable<UserData> UserData 
    {
        get
        {
            if (_userData == null)
            {
                using (myContext myContext = new myContext())
                {
                    _userData = myContext.UserData.Where(x => x.UserId == _userManager.GetUserId(_httpContextAccessor.HttpContext.User)).ToList();
                }

            }
            return _userData;
        }
    }
}
public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddScoped<ICurrentUserData, CurrentUserData>();
        services.AddHttpContextAccessor();
    }
}