两个同时发生的Ajax请求导致同一操作错误

时间:2015-12-03 15:59:03

标签: c# asp.net-mvc async-await

我有以下行动

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的屏幕截图)。注意第一次通话是如何成功的。

Error - fiddler

SingleOrDefaultAsync的代码如下:

 public  Task<T> SingleOrDefaultAsync<T>(Expression<Func<T, bool>> predicate) where T : class
    {
        return  _context.Set<T>().SingleOrDefaultAsync(predicate);
    }

我在调试时检查过,两个请求中都有电子邮件,_context不为空,并且存在请求的电子邮件的用户,但其中一个总是返回错误。错误随机返回。有时在第一次,有时在第二次ajax呼叫。

有人可以告诉我导致此错误的原因是什么?非常感谢任何帮助。

1 个答案:

答案 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?