Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/336.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# 为什么当区域控制器加载时,我的BaseController.User值==null?_C#_Asp.net Core_Asp.net Core Mvc - Fatal编程技术网

C# 为什么当区域控制器加载时,我的BaseController.User值==null?

C# 为什么当区域控制器加载时,我的BaseController.User值==null?,c#,asp.net-core,asp.net-core-mvc,C#,Asp.net Core,Asp.net Core Mvc,我正在编写一个Asp.Net核心应用程序,在获得导航访问权限之前,我已经让用户通过了Google的身份验证。当用户导航到我的“WorldBuilder”区域并点击WorldController时,BaseController.user对象为null。这是迄今为止我唯一设置的区域/控制器 当用户登录时,该用户是有效的,因为我可以迭代与该用户关联的声明。我使用默认的Asp.Net核心google身份验证,因此用户只需在登录页面上收到一个按钮,指示他们使用google进行身份验证 [Authorize

我正在编写一个Asp.Net核心应用程序,在获得导航访问权限之前,我已经让用户通过了Google的身份验证。当用户导航到我的“WorldBuilder”区域并点击WorldController时,BaseController.user对象为null。这是迄今为止我唯一设置的区域/控制器

当用户登录时,该用户是有效的,因为我可以迭代与该用户关联的声明。我使用默认的Asp.Net核心google身份验证,因此用户只需在登录页面上收到一个按钮,指示他们使用google进行身份验证

[Authorize]
[Area("WorldBuilder")]
public class WorldController : Controller
{
    private string _userId;
    private IWorldService _worldService;
    private IUserRepository _userRepository;

    public WorldController(IWorldService worldService, IUserRepository userRepository)
    {
        if (User != null) /* The user object is found to be null here. */
        {
            var userIdNameClaim = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.NameIdentifier);
            if (userIdNameClaim != null)
            {
                _userId = userIdNameClaim.Value;
            }
        }
        _userRepository = userRepository;
        _worldService = worldService;
    }

我希望,由于这些区域是同一应用程序的一部分,因此经过身份验证的用户信息将在区域之间传递,但情况似乎并非如此。BaseController.User对象为空

您可以使用HttpContextAccessorHttpContext向下传递到区域、存储库等

有关如何使用HttpContextAccessor并使用依赖注入设置它的详细信息,请参见此处


您可以使用HttpContextAccessorHttpContext向下传递到区域、存储库等

有关如何使用HttpContextAccessor并使用依赖注入设置它的详细信息,请参见此处


只能从控制器的操作中访问
用户
属性(以及其他属性,如
HttpContext
)。控制器是在执行身份验证和授权之前构造的,因此属性为null

如果需要对用户ID进行常规访问,可以在控制器上创建一个属性,从用户对象中检索用户ID,并从操作中使用该属性。您甚至可以将此属性移动到基类,并将该类用作基类控制器,以便从每个控制器访问该属性

例如:

公共类控制器base:Controller
{
公共字符串用户ID
{
得到
{
如果(User!=null)/*此处发现用户对象为null*/
{
var userIdNameClaim=User.Claims.FirstOrDefault(c=>c.Type==ClaimTypes.NameIdentifier);
if(userIdNameClaim!=null)
{
返回userIdNameClaim.Value;
}
}
返回null;
}
}
}
以及您的特定控制器:

公共类WorldController:ControllerBase
{
//承包商等。。。
public IActionResult Get()
{
var userId=userId;
//使用userId做一些事情(或直接使用userId)
}
}

您只能从控制器的操作中访问
用户
属性(以及其他属性,如
HttpContext
)。控制器是在执行身份验证和授权之前构造的,因此属性为null

如果需要对用户ID进行常规访问,可以在控制器上创建一个属性,从用户对象中检索用户ID,并从操作中使用该属性。您甚至可以将此属性移动到基类,并将该类用作基类控制器,以便从每个控制器访问该属性

例如:

公共类控制器base:Controller
{
公共字符串用户ID
{
得到
{
如果(User!=null)/*此处发现用户对象为null*/
{
var userIdNameClaim=User.Claims.FirstOrDefault(c=>c.Type==ClaimTypes.NameIdentifier);
if(userIdNameClaim!=null)
{
返回userIdNameClaim.Value;
}
}
返回null;
}
}
}
以及您的特定控制器:

公共类WorldController:ControllerBase
{
//承包商等。。。
public IActionResult Get()
{
var userId=userId;
//使用userId做一些事情(或直接使用userId)
}
}

这是因为您试图访问构造函数中的
用户
,而这是在进行任何授权之前调用的。代码中不清楚此时为什么需要用户-如果您在
操作中需要它,则
用户将在此时启动。如果
用户在ctor中为空,则
HttpContext
不能在此时由框架设置。你无法控制。为什么不将id获取逻辑提取到
ClaimsPrincipal
上的扩展方法上,然后将
\u userId
的用法替换为例如
User.GetId()
?这是因为您试图访问构造函数中的
用户
,这是在任何授权发生之前调用的。代码中不清楚此时为什么需要用户-如果您在
操作中需要它,则
用户将在此时启动。如果
用户在ctor中为空,则
HttpContext
不能在此时由框架设置。你无法控制。为什么不将id获取逻辑提取到
ClaimsPrincipal
上的扩展方法上,然后将
\u userId
的用法替换为例如
User.GetId()
?流行的建议是“在操作中这样做,而不是在构造函数中这样做”,所以我会这样做:普遍的建议是“在行动中这样做,而不是在构造器中这样做”,所以我会走这条路。:)