我有以下行动
public async Task<ActionResult> Cart(bool refresh = false, bool mobile = false)
{
var user = await Auth.GetUserAsync();
//rest of the code
}
由两个ajax调用同时调用两次(一个用于呈现移动部分,其他正常页面)。
$(document).ready(function () {
$("basket").html('<i class="fa fa-spinner fa-spin"></i>');
$('basket').load(PartialURL + "/Cart");
$('MobileBasket').load(PartialURL + "/Cart?mobile=true");
});
真正的问题出现在Auth.GetUserAsync()
函数中。
代码:
public static async Task<User> GetUserAsync()
{
if (HttpContext.Current == null || HttpContext.Current.Request == null
|| HttpContext.Current.User == null || HttpContext.Current.Request.IsAuthenticated == false)
return null;
//if session does not exist, but user is logged in, fill session information
if (HttpContext.Current.Session[sessionKey] == null && HttpContext.Current.Request.IsAuthenticated)
using (var dal = new DAL.DAL())
{
//load user from DB
var user = await dal.SingleOrDefaultAsync<User>(m => m.Email == HttpContext.Current.User.Identity.Name);
HttpContext.Current.Session[sessionKey] = user;
}
return HttpContext.Current.Session[sessionKey] as User;
}
在其中一个调用中,函数正常返回用户,但其他调用产生以下错误(来自fiddler的屏幕截图)。注意第一次通话是如何成功的。
SingleOrDefaultAsync的代码如下:
public Task<T> SingleOrDefaultAsync<T>(Expression<Func<T, bool>> predicate) where T : class
{
return _context.Set<T>().SingleOrDefaultAsync(predicate);
}
我在调试时检查过,两个请求中都有电子邮件,_context不为空,并且存在请求的电子邮件的用户,但其中一个总是返回错误。错误随机返回。有时在第一次,有时在第二次ajax呼叫。
有人可以告诉我导致此错误的原因是什么?非常感谢任何帮助。
答案 0 :(得分:5)
我认为,由于您已经进行了其他检查,HttpContext.Current.User.Identity.Name
(或甚至HttpContext.Current.User.Identity
)为空,以及导致错误的原因是什么。
如果第一个请求导致身份验证过程 start ,但该过程尚未完成,则可能是这样 - 因此null检查您是否成功,但后续成员访问失败。换句话说,您有计时问题/竞争条件。但这只是猜测。
更新:根据我的建议将名称存储在变量中并使用lambda中的变量,一切正常。但为什么呢?
我的理论是,传递给SingleOrDefaultAsync
方法的表达式包含表达式 HttpContext.User.Identity.Name
,而不是该表达式的值。
然后在您的DAL中评估此表达式,其中HttpContext.Current
(大概)null
(假设您的DAL不在您的Web项目中)。 QED?