Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/327.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# 在ASP.NET Identity GetRolesAsync中使用异步等待丢失HttpContext_C#_Asp.net Web Api_Async Await_Asp.net Identity - Fatal编程技术网

C# 在ASP.NET Identity GetRolesAsync中使用异步等待丢失HttpContext

C# 在ASP.NET Identity GetRolesAsync中使用异步等待丢失HttpContext,c#,asp.net-web-api,async-await,asp.net-identity,C#,Asp.net Web Api,Async Await,Asp.net Identity,与ASP.NET标识相比,这更像是一个异步/等待问题。我使用的是Asp.Net标识,并且有一个自定义的UserStore和一个自定义的GetRolesAsync方法。UserManager是从WebApi控制器调用的 public class MyWebApiController { private MyUserManager manager = new MyUserManager(new MyUserStore()); [HttpGet] public async Ta

与ASP.NET标识相比,这更像是一个异步/等待问题。我使用的是Asp.Net标识,并且有一个自定义的UserStore和一个自定义的GetRolesAsync方法。UserManager是从WebApi控制器调用的

public class MyWebApiController {
    private MyUserManager manager = new MyUserManager(new MyUserStore());
    [HttpGet]
    public async Task<bool> MyWebApiMethod(int x) {
        IList<string> roles = await manager.GetRolesAsync(x);
        return true;
    }
}
public class MyUserManager : UserManager<MyUser, int> {

    // I do not implement a custom GetRolesAsync in the UserManager, but 
    // from looking at the identity source, this is what the base class is doing:

    // public virtual async Task<IList<string>> GetRolesAsync(TKey userId)
    // {
    //     ThrowIfDisposed();
    //     var userRoleStore = GetUserRoleStore();
    //     var user = await FindByIdAsync(userId).WithCurrentCulture();
    //     if (user == null)
    //     {
    //         throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, Resources.UserIdNotFound,userId));
    //     }
    //     return await userRoleStore.GetRolesAsync(user).WithCurrentCulture();
    // }
}

public class MyUserStore {
    public async Task<IList<string>> GetRolesAsync(TUser user) {

        // I need HttpContext here and it is NULL. WHY??
        var currentContext = System.Web.HttpContext.Current; // NULL!

         var query = from userRole in _userRoles
                    where userRole.UserId.Equals(userId)
                    join role in _roleStore.DbEntitySet on userRole.RoleId equals role.Id
                    select role.Name;

        return await query.ToListAsync();
    }
}
公共类MyWebApicController{
private MyUserManager=new MyUserManager(new MyUserStore());
[HttpGet]
公共异步任务MyWebApiMethod(int x){
IList roles=wait manager.GetRolesAsync(x);
返回true;
}
}
公共类MyUserManager:UserManager{
//我没有在UserManager中实现自定义GetRolesAsync,但是
//从标识源来看,基类就是这样做的:
//公共虚拟异步任务GetRolesAsync(TKey用户ID)
// {
//ThrowIfDisposed();
//var userRoleStore=GetUserRoleStore();
//var user=wait FindByIdAsync(userId).WithCurrentCulture();
//if(user==null)
//     {
//抛出新的InvalidOperationException(String.Format(CultureInfo.CurrentCulture,Resources.UserIdNotFound,userId));
//     }
//return await userRoleStore.GetRolesAsync(user).WithCurrentCulture();
// }
}
公共类MyUserStore{
公共异步任务GetRolesAsync(TUser用户){
//我需要HttpContext,它是空的。为什么??
var currentContext=System.Web.HttpContext.Current;//NULL!
var query=来自_userRoles中的userRole
其中userRole.UserId.Equals(UserId)
在userRole.RoleId等于role.Id上的_roleStore.DbEntitySet中加入角色
选择角色名称;
return wait query.ToListAsync();
}
}

为什么MyUserStore.GetRolesAsync中的上下文为空?我以为Wait把上下文传下来了?我在MyUserStore中使用了其他异步方法,它们都有正确的上下文,代码看起来几乎相同。

这是
任务扩展的一个属性。WithCurrentCulture
。这些是EF的名称,但它们也适用于ASP.NET标识:

配置用于等待此任务的等待程序,以避免将继续编组回原始上下文,但保留当前区域性和UI区域性

这会导致同步上下文不封送,从而导致
HttpContext
null

以下是以下相关部分:


您正在使用的目标框架版本是什么?项目设置中的4.5.1,-web.config:尝试将应用程序中的
aspnet:UseTaskFriendlySynchronizationContext
设置为
true
。您正在调用
任务。在任何地方运行
吗?我想知道
WithCurrentCulture
是否阻止了常规的SyncCtx捕获。@用户确定。至少有文件记载:)
public void UnsafeOnCompleted(Action continuation)
{
    var currentCulture = Thread.CurrentThread.CurrentCulture;
    var currentUiCulture = Thread.CurrentThread.CurrentUICulture;

    // This part is critical.
    _task.ConfigureAwait(false).GetAwaiter().UnsafeOnCompleted(() =>
    {
        var originalCulture = Thread.CurrentThread.CurrentCulture;
        var originalUiCulture = Thread.CurrentThread.CurrentUICulture;
        Thread.CurrentThread.CurrentCulture = currentCulture;
        Thread.CurrentThread.CurrentUICulture = currentUiCulture;
        try
        {
            continuation();
        }
        finally
        {
            Thread.CurrentThread.CurrentCulture = originalCulture;
            Thread.CurrentThread.CurrentUICulture = originalUiCulture;
        }
    });
}