在大约有100多个用户登录网站的环境中 表单身份验证,调用HttpContext.Current.User.Identity.Name 返回正确登录的用户。
但是,有10%的时间会返回错误的用户全名信息。 我的测试机器上从未出现过这样的问题,只在生产中发生。我无法在我的测试机器上为许多用户重新创建相同的环境。
这个应用程序的逻辑:
1)用户输入用户名并通过,通过SQL DB调用查询信息,如果匹配,用户通过验证 FormsAuthentication.RedirectFromLoginPage(username,false)
FormsAuthentication.SetAuthCookie(user.SYS_Users_ID.ToString(), false);
if (Request["ReturnURL"] == null)
FormsAuthentication.RedirectFromLoginPage(user.SYS_Users_ID.ToString(), false);
else
Response.Redirect("/" + SysConfig.ApplicationName + appConfig.DefaultPages.DefaultPage);
2)重定向后,我将用户全名放入隐藏字段
if (!IsPostBack)
userFullName.Value = Helper.GetCurrentUserFullName();
...
public static string GetCurrentUserFullName()
{
string _userFullName = string.Empty;
try
{
_userFullName = new AgrotMasofim.DAL.Users.Users().GetUserFullName(GetCurrentUserID());
}
catch (Exception ex)
{
Logs.WriteToFileLog(string.Empty,ex);
}
return _userFullName;
}
public static Decimal GetCurrentUserID()
{
Decimal _userID = 0;
if (HttpContext.Current.User != null)
{
try
{
_userID = Convert.ToDecimal(HttpContext.Current.User.Identity.Name);
}
catch (Exception ex)
{
Logs.WriteToFileLog(string.Empty, ex);
}
}
return _userID;
}
3)在用户访问的所有页面上,他/她的信息显示在母版页上的标签内
lblUserName.Text = HttpUtility.HtmlDecode("Hello " + userFullName.Value);
这几乎一直都有效。任何想法为什么它可能会失败 不时?
答案 0 :(得分:1)
如果没有更多代码,我只能猜测你的问题。由于其他人可能会发现您的问题并遇到类似问题,我猜您的问题在于错误使用静态类或属性。
您的GetCurrentUserFullName()
方法可能依赖于在所有线程之间静态共享的数据访问方法。在数据访问类中可能存在竞争条件,这有时导致在检索数据之前被搜索的用户的id被替换为来自另一请求的用户的id。解决方案是:(a)在数据访问类的所有关键部分使用锁,或者(b)使用为每个请求实例化新数据访问类的解决方案(实际上每个工作单元) )。后一种设计要求您的数据访问类是轻量级的,但更好,因为它也更容易测试。
如果您在静态属性或其他将在线程之间共享的静态类中缓存值,那么您也可能具有类似的竞争条件,其中这些值被缓存和使用。类似的解决方案将适用 - 使用锁定或使用每线程实例而不是静态实例。