2016-03-21 26 views
1

viewModeluser nesnesinden farklıysa, kullanıcıyı oturum açıp kullanıcıyı güncelleştirmeye çalışan bir yöntem var. Gördüğüm davranış kafa karıştırıcı. "There is no user with id: 99" (ya da id değeri):Neden UpdateAsync (kullanıcı) yöntemim ilk kez başarısız oluyor, kullanıcı bulunamıyor?

yöntem her çalıştırıldığında user önceden kaydedilir değil ise, hat await _userManager.UpdateAsync(user); dışında başarısız olur. Ancak, userdaha önce giriş yapmış olan ise, satır çalışır. Örneğin bu şekilde

,

  1. Kullanıcı uygulaması (an giriş yapmadın) başlatıldığında ve sunucuya viewModel göndermek için düğmesini tıklar. viewModel mevcut user 'ın verilerden farklı ise
  2. uygulama sunucusu güncellemek için çalışır, içinde user,
  3. kaydeder.
  4. Bu güncelleştirme, "There is no user with id: 99"
  5. ile tekrar başarısız olur ve aynı verileri sunucuya gönderir.
  6. viewModel hala mevcut veri (güncelleme başarısız son kez hatırlayamıyorum)
  7. await _userManager.UpdateAsync(user); eser farklıdır (bu sefer user önceki başarısız görevinden oturum edilmiştir) ve kayıt güncellenir.

    [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); 
        } 
    } 
    

    ben id 99 sahip bir kullanıcı aslında veritabanında mevcut yapar teyit edebiliriz:

aşağıdaki yöntemdir.

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'[email protected]' 
: Kayıt için

aşağıdaki güncellemeden önce işletilirse ex.StackTrace

at Abp.Authorization.Users.AbpUserManager`3.<GetUserByIdAsync>d__5b.MoveNext() 
--- End of stack trace from previous location where exception was thrown --- 
    at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) 
    at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 
    at Abp.Authorization.Users.AbpUserManager`3.<UpdateAsync>d__64.MoveNext() 
--- End of stack trace from previous location where exception was thrown --- 
    at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) 
    at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 
    at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult() 
    at MyProject.Web.Controllers.Api.AccountApiController.<Post>d__16.MoveNext() in C:\dev\MyProject\MyProject.Web\Controllers\Api\AccountApiController.cs:line 146 

içeriği Bir ipucu (SQL Server Profiler ile yakalanan) Aşağıdaki sorguda olabileceğini düşünüyorum

Burada @DynamicFilterParam_1=NULL görüyoruz. @DynamicFilterParam_1 değişkeni [Extent1].[TenantId] değerine karşılık gelir. 2 değerini (db'deki kayıtla ilişkili değer olan) NULL yerine el ile atarsam ve sorguyu yeniden çalıştırırsam, beklediğim gibi kaydı verir.

I yöntem olup ikinci zaman çalıştırmak zaman, TenantId doğru TenantId tekabül eden değer NULL ilk kez tahsis edilmektedir neden 2.

değeri atanır görebilir? Neden her ilk kez UpdateAsync yöntemi başarısız oluyor? Çalıştırmak için ne yapabilirim? Aşağıdaki talebe yanıt olarak

, UpdateAsync tanımı Bu, çoklu müşteri ait the asp.net boilerplate github

+2

pls UpdateAsync için kaynak bir bağlantı ekledik UpdateAsync – Viru

+0

kodunu sonrası olduğunu. GitHub'da. – DaveDev

+0

Merhaba, @DaveDev, Şu anda aynı sorunla karşı karşıyayım. Tesadüfen bir çözüm buldunuz mu? – Vlad

cevap

0

mevcuttur.ABP, kullanıcı girişi yapmadan önce TenantId'yi tanımıyor. Kullanıcının kiracısına geçmek için kiracı kimliğini el ile ayarlamanız gerekir. Benim Girişi kodu böyledir:

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 }); 
    } 
} 

kritik şey (UnitOfWorkManager.Current.SetTenantId(tenantId)) deyimi kullanılarak

+0

Efsane. Teşekkürler. – DaveDev

İlgili konular