Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/260.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么我的UpdateAsync(user)方法第一次失败,声称用户没有';不存在?_C#_Entity Framework_Asp.net Boilerplate - Fatal编程技术网

C# 为什么我的UpdateAsync(user)方法第一次失败,声称用户没有';不存在?

C# 为什么我的UpdateAsync(user)方法第一次失败,声称用户没有';不存在?,c#,entity-framework,asp.net-boilerplate,C#,Entity Framework,Asp.net Boilerplate,如果viewModel与user对象不同,我有一种方法可以让用户登录并尝试更新用户。我看到的行为令人困惑 每次执行该方法时,如果用户之前未登录,则行wait\u userManager.UpdateAsync(用户)失败,例外情况是:“没有id为99的用户”(或任何id值)。但是,如果用户以前登录过,则该行可以工作 那么比如说, 用户启动应用程序(当前未登录)并单击按钮将viewModel发布到服务器 应用程序将用户记录在 如果viewModel与现有用户的数据不同,服务器将尝试更新该数据 此更

如果
viewModel
user
对象不同,我有一种方法可以让用户登录并尝试更新用户。我看到的行为令人困惑

每次执行该方法时,如果
用户
之前未登录,则行
wait\u userManager.UpdateAsync(用户)失败,例外情况是:
“没有id为99的用户”
(或任何
id
值)。但是,如果
用户以前登录过,则该行可以工作

那么比如说,

  • 用户启动应用程序(当前未登录)并单击按钮将
    viewModel
    发布到服务器
  • 应用程序将
    用户
    记录在
  • 如果
    viewModel
    与现有
    用户的数据不同,服务器将尝试更新该数据
    
  • 此更新将失败,因为
    “没有id为99的用户”
  • 用户再次单击按钮并将相同的数据发布到服务器。(这次
    用户已从上一次失败的post登录)
  • viewModel
    仍与现有数据不同(请记住,上次更新失败)
  • wait\u userManager.UpdateAsync(用户)工作并更新记录
  • 方法如下:

    [UnitOfWork]
    public async Task<AjaxResponse> Post(MyViewModel viewModel)
    {
        try
        {
            var loginResult = await _userManager.LoginAsync(viewModel.UserName, viewModel.Password, viewModel.TenancyName);
    
            User user;
            if (loginResult.Result == AbpLoginResultType.Success)
            {
                await SignInAsync(loginResult.User, loginResult.Identity);
    
                user = loginResult.User;
    
                if (user.AccessToken != viewModel.AccessToken)
                {
                    user.AccessToken = viewModel.AccessToken;
    
                    // why does this fail the first time?
                    await _userManager.UpdateAsync(user);
                }
            }
            else 
            { 
                /* do some other UnitOfWork stuff below */
            }
    
    
            return new AjaxResponse(new MyResult
            {
                Name = user.Name + " " + user.Surname,
                UserName = user.UserName,
                EmailAddress = user.EmailAddress,
                IsActive = user.IsActive,
                Success = true,
                UserId = user.UserId,
            });
        }
        catch (Exception ex)
        {
            throw new HttpException((int)HttpStatusCode.InternalServerError, ex.Message);
        }
    }
    
    我认为更新之前执行的以下查询(SQL Server Profiler截取)中可能有一条线索:

    exec sp_executesql N'SELECT TOP (1) 
        [Extent1].[Id] AS [Id], 
        [Extent1].[AccessToken] AS [AccessToken], 
        [Extent1].[UserId] AS [UserId], 
        [Extent1].[EmailAddress] AS [EmailAddress], 
        [Extent1].[TenantId] AS [TenantId], 
        [Extent1].[IsDeleted] AS [IsDeleted], 
        -- irrelevant stuff removed
        FROM [dbo].[AbpUsers] AS [Extent1]
        WHERE 
                ((([Extent1].[TenantId] IS NULL) AND (@DynamicFilterParam_1 IS NULL)) 
            OR  (([Extent1].[TenantId] IS NOT NULL) AND ([Extent1].[TenantId] = @DynamicFilterParam_1)) 
            OR (@DynamicFilterParam_2 IS NOT NULL)) AND (([Extent1].[IsDeleted] = @DynamicFilterParam_3) 
            OR (@DynamicFilterParam_4 IS NOT NULL)) AND ([Extent1].[EmailAddress] = @p__linq__0)',
            N'@DynamicFilterParam_1 int,@DynamicFilterParam_2 bit,@DynamicFilterParam_3 bit,@DynamicFilterParam_4 bit,@p__linq__0 nvarchar(4000)'
            ,@DynamicFilterParam_1=NULL,@DynamicFilterParam_2=NULL,@DynamicFilterParam_3=0,@DynamicFilterParam_4=NULL,@p__linq__0=N'myemail@mail.com'
    
    在这里,我们可以看到
    @DynamicFilterParam\u 1=NULL
    。变量
    @DynamicFilterParam_1
    对应于
    [Extent1].[TenantId]
    的值。如果我手动分配值
    2
    (这是与数据库中的记录相关联的值),而不是
    NULL
    ,然后重新运行查询,它将按预期返回记录

    当我第二次执行该方法时,我可以看到TenantId被正确地赋值为2

    为什么第一次为TenantId对应的值赋值为空?为什么
    UpdateAsync
    方法每次都失败?我能做些什么使它工作


    作为对以下请求的响应,UpdateSync的定义在

    中提供,这是因为多租户。ABP在用户登录之前不知道租户。您应该手动设置租户id以切换到用户的租户。我的登录代码如下:

    public virtual async Task<JsonResult> Login(LoginViewModel loginModel, string returnUrl = "", string returnUrlHash = "")
    {
        var loginResult = await GetLoginResultAsync(loginModel.UsernameOrEmailAddress, loginModel.Password, loginModel.TenancyName);
    
        var tenantId = loginResult.Tenant == null ? (int?)null : loginResult.Tenant.Id;
    
        using (UnitOfWorkManager.Current.SetTenantId(tenantId))
        {
            if (loginResult.User.ShouldChangePasswordOnNextLogin)
            {
                loginResult.User.SetNewPasswordResetCode();
    
                return Json(new AjaxResponse
                {
                    TargetUrl = Url.Action(
                        "ResetPassword",
                        new ResetPasswordViewModel
                        {
                            TenantId = tenantId,
                            UserId = SimpleStringCipher.Instance.Encrypt(loginResult.User.Id.ToString()),
                            ResetCode = loginResult.User.PasswordResetCode
                        })
                });
            }
    
            var signInResult = await _signInManager.SignInOrTwoFactorAsync(loginResult, loginModel.RememberMe);
            if (signInResult == SignInStatus.RequiresVerification)
            {
                return Json(new AjaxResponse
                {
                    TargetUrl = Url.Action(
                        "SendSecurityCode",
                        new
                        {
                            returnUrl = returnUrl + (returnUrlHash ?? ""),
                            rememberMe = loginModel.RememberMe
                        })
                });
            }
    
            Debug.Assert(signInResult == SignInStatus.Success);
    
            await UnitOfWorkManager.Current.SaveChangesAsync();
    
            if (string.IsNullOrWhiteSpace(returnUrl))
            {
                returnUrl = GetAppHomeUrl();
            }
    
            if (!string.IsNullOrWhiteSpace(returnUrlHash))
            {
                returnUrl = returnUrl + returnUrlHash;
            }
    
            return Json(new AjaxResponse { TargetUrl = returnUrl });
        }
    }
    
    公共虚拟异步任务登录(LoginViewModel loginModel,string returnUrl=“”,string returnUrlHash=“”)
    {
    var loginResult=await GetLoginResultAsync(loginModel.UserName或MailAddress、loginModel.Password、loginModel.TenancyName);
    var tenantId=loginResult.Tenant==null?(int?)null:loginResult.Tenant.Id;
    使用(UnitOfWorkManager.Current.SetTenantId(tenantId))
    {
    if(loginResult.User.ShouldChangePasswordOnNextLogin)
    {
    loginResult.User.SetNewPasswordResetCode();
    返回Json(新的AjaxResponse
    {
    TargetUrl=Url.Action(
    “重置密码”,
    新的ResetPasswordViewModel
    {
    TenantId=TenantId,
    UserId=SimpleStringCipher.Instance.Encrypt(loginResult.User.Id.ToString()),
    ResetCode=loginResult.User.PasswordResetCode
    })
    });
    }
    var signInResult=wait _signInManager.signinorTwofactorSync(loginResult,loginModel.RememberMe);
    if(signInResult==SignInStatus.RequiresVerification)
    {
    返回Json(新的AjaxResponse
    {
    TargetUrl=Url.Action(
    “SendSecurityCode”,
    新的
    {
    returnUrl=returnUrl+(returnUrlHash???),
    rememberMe=loginModel.rememberMe
    })
    });
    }
    Assert(signInResult==SignInStatus.Success);
    等待UnitOfWorkManager.Current.SaveChangesSync();
    if(string.IsNullOrWhiteSpace(returnUrl))
    {
    returnUrl=GetAppHomeUrl();
    }
    如果(!string.IsNullOrWhiteSpace(returnUrlHash))
    {
    returnUrl=returnUrl+returnUrlHash;
    }
    返回Json(新的AjaxResponse{TargetUrl=returnUrl});
    }
    }
    

    关键是使用
    (UnitOfWorkManager.Current.SetTenantId(tenantId))
    语句,这是因为多租户。ABP在用户登录之前不知道租户。您应该手动设置租户id以切换到用户的租户。我的登录代码如下:

    public virtual async Task<JsonResult> Login(LoginViewModel loginModel, string returnUrl = "", string returnUrlHash = "")
    {
        var loginResult = await GetLoginResultAsync(loginModel.UsernameOrEmailAddress, loginModel.Password, loginModel.TenancyName);
    
        var tenantId = loginResult.Tenant == null ? (int?)null : loginResult.Tenant.Id;
    
        using (UnitOfWorkManager.Current.SetTenantId(tenantId))
        {
            if (loginResult.User.ShouldChangePasswordOnNextLogin)
            {
                loginResult.User.SetNewPasswordResetCode();
    
                return Json(new AjaxResponse
                {
                    TargetUrl = Url.Action(
                        "ResetPassword",
                        new ResetPasswordViewModel
                        {
                            TenantId = tenantId,
                            UserId = SimpleStringCipher.Instance.Encrypt(loginResult.User.Id.ToString()),
                            ResetCode = loginResult.User.PasswordResetCode
                        })
                });
            }
    
            var signInResult = await _signInManager.SignInOrTwoFactorAsync(loginResult, loginModel.RememberMe);
            if (signInResult == SignInStatus.RequiresVerification)
            {
                return Json(new AjaxResponse
                {
                    TargetUrl = Url.Action(
                        "SendSecurityCode",
                        new
                        {
                            returnUrl = returnUrl + (returnUrlHash ?? ""),
                            rememberMe = loginModel.RememberMe
                        })
                });
            }
    
            Debug.Assert(signInResult == SignInStatus.Success);
    
            await UnitOfWorkManager.Current.SaveChangesAsync();
    
            if (string.IsNullOrWhiteSpace(returnUrl))
            {
                returnUrl = GetAppHomeUrl();
            }
    
            if (!string.IsNullOrWhiteSpace(returnUrlHash))
            {
                returnUrl = returnUrl + returnUrlHash;
            }
    
            return Json(new AjaxResponse { TargetUrl = returnUrl });
        }
    }
    
    公共虚拟异步任务登录(LoginViewModel loginModel,string returnUrl=“”,string returnUrlHash=“”)
    {
    var loginResult=await GetLoginResultAsync(loginModel.UserName或MailAddress、loginModel.Password、loginModel.TenancyName);
    var tenantId=loginResult.Tenant==null?(int?)null:loginResult.Tenant.Id;
    使用(UnitOfWorkManager.Current.SetTenantId(tenantId))
    {
    if(loginResult.User.ShouldChangePasswordOnNextLogin)
    {
    loginResult.User.SetNewPasswordResetCode();
    返回Json(新的AjaxResponse
    {
    TargetUrl=Url.Action(
    “重置密码”,
    新的ResetPasswordViewModel
    {
    TenantId=TenantId,
    UserId=SimpleStringCipher.Instance.Encrypt(loginResult.User.Id.ToString()),
    ResetCode=loginResult.User.PasswordResetCode
    })
    });
    }
    var signInResult=wait _signInManager.signinorTwofactorSync(loginResult,loginModel.RememberMe);
    if(signInResult==SignInStatus.RequiresVerification)
    {
    返回Json(新的AjaxResponse
    {