【问题标题】:ASP.NET Membership: Where is Current User ID Stored?ASP.NET 成员资格:当前用户 ID 存储在哪里?
【发布时间】:2014-03-04 06:47:20
【问题描述】:

使用 ASP.NET 成员资格,如果我想获取当前用户的信息,可以拨打MembershipUser.GetUser()

因此,系统必须以某种方式知道当前用户的 ID。

如果这是正确的,并且我想要的只是当前用户的 ID,有没有办法在不从数据库返回所有用户信息的情况下获取它?

我知道我可以使用User.Identity.Name 获取当前用户的用户名,但我需要 ID。

【问题讨论】:

    标签: asp.net asp.net-membership


    【解决方案1】:

    简短的回答是不,当您使用内置的会员服务提供商时,您不能只获取用户 ID 而不会检索整个用户信息,只能这样

        MembershipUser user = Membership.GetUser();
        string UserID = user.ProviderUserKey.ToString();
    

    但是如果你想拥有只检索用户 ID 的方法或属性,你必须重新实现自己的成员资格提供程序或(很简单)实现 IPrincipal 接口

    【讨论】:

      【解决方案2】:

      要返回 UserId,请在控制器中使用以下命令:

      User.Identity.GetUserId();
      

      要返回用户名,请使用:

      User.Identity.Name;
      

      返回用户:

      var user = db.Users.Find(User.Identity.GetUserId());
      

      请参考帖子:How to get current user, and how to use User class in MVC5?

      【讨论】:

        【解决方案3】:

        如您所料,Membership API 不支持您想要的开箱即用功能。过去,我使用辅助类而不是创建自己的提供程序。在这种情况下,它很简单,可能是这样的:

        public static object GetUserId() {
          return GetUserId(HttpContext.Current.User.Identity.Name, true);
        }    
        public static object GetUserId(string userName) {
          return GetUserId(userName, true);
        }
        public static object GetUserId(string userName, bool UpdateLastActivity) {
          using (SqlConnection c = new SqlConnection(CONNECTION_STRING)) {
            string sql = @"
        DECLARE @UserId uniqueidentifier
        SELECT @UserId=u.UserId
        FROM dbo.aspnet_Applications AS a
          ,dbo.aspnet_Users AS u
          ,dbo.aspnet_Membership AS m
        WHERE
          a.LoweredApplicationName=LOWER(@ApplicationName)
          AND u.ApplicationId=a.ApplicationId
          AND u.LoweredUserName=LOWER(@UserName)
          AND u.UserId=m.UserId;
        IF @UserId IS NOT NULL AND @UpdateLastActivity=1
          UPDATE dbo.aspnet_Users
          SET LastActivityDate=@CurrentTimeUtc
          WHERE UserId=@UserId;
        SELECT @UserId  
              ";
            using (SqlCommand cmd = new SqlCommand(sql, c)) {
              cmd.Parameters.AddWithValue("@ApplicationName", Roles.ApplicationName);
              cmd.Parameters.AddWithValue("@UserName", userName);
              cmd.Parameters.AddWithValue("@UpdateLastActivity", UpdateLastActivity);
              cmd.Parameters.AddWithValue("@CurrentTimeUtc", DateTime.UtcNow);
              object id = null;
              c.Open();
              id = cmd.ExecuteScalar();
              return id != DBNull.Value ? id : null;
            }
          }
        }
        

        以上内容与调用 GetUser() 时在 Membership API 中所做的非常相似

        【讨论】:

        • 我正在寻找的是重量更轻的东西,因为我可以看到 ASP.NET 正在缓存一些此类信息。我真的看不出使用您的代码比 Membership.GetUser().ProviderUserKey 之类的简单代码有什么优势。
        • 如果您查看aspnetdb 数据库中的aspnet_Membership_GetUserByName 存储过程,查询的字段之一具有ntext 数据类型。您没有详细说明您的设置是什么,因此这可能是也可能不是问题。但是,您错过了致电Membership.GetUser().ProviderUserKey 的重点。您获得了用户 ID,但 Membership.GetUser() 正在执行 aspnet_Membership_GetUserByName - 通过 SQL Server Profiler 运行它以确认。不过,从不费心检查 ASP.NET 正在缓存什么。
        • 我不确定我是否明白你的意思。是的,Membership.GetUser() 返回整个用户记录——我原本想看看是否可以避免。但是看看您发布的代码的复杂性,我并没有真正看到它会变得更快。所以我不确定我是否真的看到了很大的优势。对不起,我错过了你关于ntext 的观点。为什么会有问题? (我正在使用关于所有内容的最新版本。)
        • aspnet_Membership_GetUserByName 查询 11 个字段,包括 aspnet_Membership.dbo.Comment,这是 SQL Server 中的 poorest performing 数据库类型之一。根据您的问题,一个合理的假设是您想要任何 可能的优化。回答会减少网络流量,尤其是如果您正在在您的设置中使用MembershipUser.Comment(未在问题中指定)。请不要将其视为个人,但如果您认为答案是“complex”,那么您最好坚持使用Membership.GetUser().ProviderUserKey(差异对您来说并不重要)。祝你好运。
        • 是的,我个人认为。这只是一个权衡的问题——不是我无法处理的太复杂的问题!除此之外,您为什么不能只更改数据库中的ntext 列类型?
        【解决方案4】:

        您可以使用MembershipUser.UserName 获取用户ID 或尝试调用Membership.GetUser(User.Identity.Name) 看看是否适合您。

        【讨论】:

        • 不,那是用户名,不是 ID。我的问题是如何在不检索所有用户数据的情况下获得此信息,这正是您的建议所做的。
        • 试试我编辑后发布的Membership.GetUser(User.Identity.Name)
        • 您已经描述了多种方法来做我不想想做的事情。也许您没有阅读我的问题。
        • 另一个呢? MembershipUser myObject = Membership.GetUser(); string UserID = myObject.ProviderUserKey.ToString();我相信这就是你要找的。​​span>
        • 当然可以。但它需要读取整个用户记录才能获得 ID。这正是我在我的问题中所说的,我确实不想想要做。我不清楚你为什么不理解我,感谢你的努力,但我想我已经完成了这次谈话。
        【解决方案5】:

        进一步研究后,似乎 ASP.NET Membership API 根本不跟踪用户 ID。它必须只跟踪用户名 (User.Identity.Name)。 ID 不是必需的,因为Membership.GetUser() 可以从 ID 用户名中找到用户。

        事实上,Membership.GetUser() 必须简单地转换为Membership.GetUser(User.Identity.Name)。由于它可以从用户名中获取当前用户,因此不再有任何理由假设当前用户ID被缓存在任何地方。

        所以看起来ID没有加载到内存中,获取ID的唯一方法是从数据库中加载数据(这意味着在使用ASP.NET Membership API时加载整个用户记录)。

        【讨论】:

        • 会员用户应该有一个 ProviderUserKey 属性,假设您使用的是 SQLMembershipProvider,您可以强制转换 (Guid)。
        【解决方案6】:

        考虑

        int userId = WebSecurity.CurrentUserId;
        

        信用:https://stackoverflow.com/a/15382691/1268910

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-08-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-02-08
          相关资源
          最近更新 更多