ASP.NET成员身份:当前用户ID存储在哪里?

ASP.NET成员身份:当前用户ID存储在哪里?,asp.net,asp.net-membership,Asp.net,Asp.net Membership,使用ASP.NET成员资格,如果要获取当前用户的信息,可以调用MembershipUser.GetUser() 因此,系统必须知道当前用户的ID 如果这是正确的,并且我只需要当前用户的ID,那么有没有一种方法可以在不从数据库返回所有用户信息的情况下获取它 我知道我可以使用user.Identity.Name获取当前用户的用户名,但我需要ID。您可以使用MembershipUser.username获取用户ID或尝试调用Membership.GetUser(user.Identity.Name)然

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

因此,系统必须知道当前用户的ID

如果这是正确的,并且我只需要当前用户的ID,那么有没有一种方法可以在不从数据库返回所有用户信息的情况下获取它


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

您可以使用
MembershipUser.username
获取用户ID或尝试调用
Membership.GetUser(user.Identity.Name)
然后看看这是否对您有效。

简短的回答是“不”,当您使用内置的成员资格提供程序时,如果不检索整个用户信息,您就无法获取唯一的用户ID,只有通过此

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

但是,如果您想拥有只检索用户ID的方法或属性,则必须重新实现自己的成员资格提供程序,或者(简单地说)要实现IPrincipal接口,在进一步研究之后,ASP.NET成员资格API似乎根本不跟踪用户ID。它必须只跟踪用户名(
user.Identity.name
)。该ID不是必需的,因为
Membership.GetUser()
可以从ID或用户名中找到用户

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


因此,ID似乎没有加载到内存中,获取ID的唯一方法是从数据库加载数据(这意味着在使用ASP.NET成员资格API时加载整个用户记录)。

正如您所猜测的,成员资格API不支持您想要的开箱即用。在过去,我使用了一个helper类,而不是创建自己的提供者。在这种情况下,它非常简单,可能是这样的:

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

时,上面的操作与成员API中的操作非常相似

int userId = WebSecurity.CurrentUserId;

信用证:

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

User.Identity.GetUserId();
要返回用户名,请使用:

User.Identity.Name;
要返回用户,请执行以下操作:

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

请参阅帖子:

否,这是用户名,而不是ID。我的问题是如何在不检索所有用户数据的情况下获取此信息,这正是您的建议。请尝试编辑
Membership.GetUser(user.Identity.Name)后发布的帖子
您已经描述了多种方法来完成我不想做的事情。也许你没读过我的问题。另一个呢<代码>MembershipUser myObject=Membership.GetUser();字符串UserID=myObject.ProviderUserKey.ToString()我相信这就是你要找的。它当然有效。但它需要读取整个用户记录才能获得ID。这正是我在问题中所说的我不想做的。我不清楚你为什么不理解我,谢谢你的努力,但我想我已经结束了这次对话。鉴于我可以看到ASP.NET正在缓存一些信息,我想要的是更轻的东西。我并不认为使用代码比使用
Membership.GetUser().ProviderUserKey
这样简单的东西有什么好处。如果您查看
aspnetdb
数据库中的
aspnet\u Membership\u GetUserByName
存储过程,查询的字段之一具有
ntext
数据类型。您没有详细说明您的设置是什么,因此这可能是一个问题,也可能不是一个问题。但是,您缺少调用
Membership.GetUser().ProviderUserKey
的要点。您获得了用户ID,但
Membership.GetUser()
正在执行
aspnet\u Membership\u GetUserByName
-通过SQL Server Profiler运行它以确认。尽管如此,我从不费心检查ASP.NET缓存的内容。我不确定我是否理解你的意思。是的,
Membership.GetUser()
返回整个用户记录——这是我最初想看看是否可以避免的。但从你发布的代码的复杂性来看,我并不认为它会快得多。所以我不确定我是否真的看到了一个很大的优势。对不起,我没有领会你关于
ntext
的要点。为什么会成为一个问题?(我使用的是about everything的最新版本。)
aspnet_Membership\u GetUserByName
查询11个字段,包括
aspnet_Membership.dbo.Comment
,这是SQL Server中的一种数据库类型。基于您的问题,一个合理的假设是您需要任何可能的优化。Answer可减少网络流量,特别是当您在设置中使用
MembershipUser.Comment
(未在问题中指定)时。请不要认为这是针对个人的,但如果您认为答案“复杂”,最好还是坚持使用
Membership.GetUser().ProviderUserKey
(不同之处对您并不重要)。祝你好运。是的,我认为这是我个人的事。这只是一个权衡的问题——不是什么对我来说太复杂而难以处理的问题!除此之外,为什么不能更改数据库中的
ntext
列类型?membershipuser应该具有ProviderUserKey属性,假设您使用的是SQLMembershipProvider,您可以强制转换该属性(Guid)。