我正在f#中构建.NET Core Web应用程序,并正在尝试设置身份。我有一个寄存器方法的基本版本,该版本可在数据库中创建用户并创建cookie:
[<HttpPost>]
[<AllowAnonymous>]
member this.Register([<FromBody>]model: RegisterViewModel) =
if not (isNull model.Email) && model.Password = model.ConfirmPassword then
let user = ApplicationUser(userName = model.Email, email = model.Email, password = model.Password)
let result = userManager.CreateAsync(user, model.Password) |> Async.AwaitTask |> Async.RunSynchronously
if result.Succeeded then
signInManager.SignInAsync(user, isPersistent = false) |> Async.AwaitTask |> Async.RunSynchronously
true
else
false
else
false
但是,我的登录实现挂起:
[<HttpPost>]
[<AllowAnonymous>]
member this.Login([<FromBody>]model: LoginViewModel) =
if not (isNull model.Email && isNull model.Password) then
let result = signInManager.PasswordSignInAsync(model.Email, model.Password, false, lockoutOnFailure = false) |> Async.AwaitTask |> Async.RunSynchronously
if result.Succeeded then true else false
else
false
这是应用程序悬挂的地方:
info: Microsoft.EntityFrameworkCore.Storage.IRelationalCommandBuilderFactory[1]
Executed DbCommand (5ms) [Parameters=[@__normalizedUserName_0='?' (Size = 256)], CommandType='Text', CommandTimeout='30']
SELECT TOP(1) [u].[Id], [u].[AccessFailedCount], [u].[ConcurrencyStamp], [u].[Email], [u].[EmailConfirmed], [u].[LockoutEnabled], [u].[LockoutEnd], [u].[NormalizedEmail], [u].[NormalizedUserName], [u].[PasswordHash], [u].[PhoneNumber], [u].[PhoneNumberConfirmed], [u].[SecurityStamp], [u].[TwoFactorEnabled], [u].[UserName]
FROM [AspNetUsers] AS [u]
WHERE [u].[NormalizedUserName] = @__normalizedUserName_0
知道问题可能是什么?
根据本文,处理程序可以是 async
(在C#sense中),因此将路由手柄重写为非障碍是有意义的,因此可以删除Async.RunSynchronously
引起问题。
我们可以在f# async
工作流程中编写实际逻辑,因为那是更iDostic,然后将其转换为 Task<_>
,以匹配预期的C#签名。
[<HttpPost>]
[<AllowAnonymous>]
member this.Login([<FromBody>]model: LoginViewModel) =
async {
if not (isNull model.Email && isNull model.Password)
then
let! result =
signInManager.PasswordSignInAsync(model.Email, model.Password, false, lockoutOnFailure = false)
|> Async.AwaitTask
return result.Succeeded
else
return false
}
|> Async.StartAsTask
死锁可能很难追捕,因此,当使用F#async
时,您应该尝试在应用程序中只有一个对Async.RunSynchronously
的呼叫,通常在" Main"中方法。