Ich habe eine Methode, die einen Benutzer anmeldet und versucht, den Benutzer zu aktualisieren, wenn der viewModel
sich von user
Objekt unterscheidet. Das Verhalten, das ich sehe, ist verwirrend.Warum schlägt meine UpdateAsync (user) -Methode beim ersten Mal fehl, und behauptet, Benutzer existiert nicht?
Jedes Mal, wenn die Methode ausgeführt wird, wenn die user
nicht vorher angemeldet wurde, schlägt die Linie await _userManager.UpdateAsync(user);
mit Ausnahme: "There is no user with id: 99"
(oder was auch immer id
Wert). Wenn jedoch die user
zuvor angemeldet war, funktioniert die Linie.
So zum Beispiel,
- Benutzer starten die App (momentan nicht angemeldet) und klickt Schaltfläche
viewModel
zum Server zu senden. - Die App protokolliert die
user
in, - Wenn die
viewModel
anders als die bestehendenuser
‚s Daten vorhanden sind, versucht der Server, um es zu aktualisieren. - Dieses Update schlägt mit
"There is no user with id: 99"
- Benutzer klickt erneut und sendet die gleichen Daten auf dem Server. (Diesmal
user
wurde von früheren gescheiterten Post angemeldet) viewModel
als die bestehenden Daten noch anders ist (denken Sie daran, das Update fehlgeschlagen letzte Mal)await _userManager.UpdateAsync(user);
Werke und der Datensatz aktualisiert wird.
Im folgenden ist die Methode:
[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);
}
}
ich, dass ein Benutzer mit der ID 99 tut in der Tat in der Datenbank vorhanden sein bestätigen kann.
Für die Aufzeichnung ist das folgende der Inhalt von 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
Ich denke, ein Hinweis auf die folgende Abfrage sein könnte (abgefangen mit SQL Server Profiler), die vor dem Update ausgeführt wird:
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]'
Hier können wir sehen, dass @DynamicFilterParam_1=NULL
. Die Variable @DynamicFilterParam_1
entspricht dem Wert für [Extent1].[TenantId]
. Wenn ich manuell den Wert 2
(der Wert ist, der dem Datensatz in der Datenbank zugeordnet ist) statt NULL
zuweisen und die Abfrage erneut ausführen, wird der Datensatz wie erwartet zurückgegeben.
Wenn ich die Methode zum zweiten Mal ausführen, kann ich sehen, daß TenantId korrekt, den Wert von 2.
zugeordnet Deshalb wird der Wert auf TenantId NULL entspricht das erste Mal zugewiesen wird? Warum schlägt die Methode jedes Mal fehl? Was kann ich tun, damit es funktioniert?
Als Antwort auf die Anfrage unten, ist die Definition von UpdateAsync in the asp.net boilerplate github
pls den Code UpdateAsync Post – Viru
Ich habe einen Link auf die Quelle für UpdateAsync hinzugefügt. Es ist auf GitHub. – DaveDev
Hallo, @DaveDev, ich habe gerade das gleiche Problem. Haben Sie zufällig eine Lösung gefunden? – Vlad