【问题标题】:Value cannot be null. (Parameter 'value')值不能为空。 (参数“值”)
【发布时间】:2021-08-09 23:30:42
【问题描述】:

我创建了一个方法,用户可以登录到我的应用程序,然后将令牌发送给用户,以便它可以用于查看应用程序中的任何其他视图。当我在邮递员上测试登录方法时,我得到了500 服务器错误如下而不是令牌。我看过类似的问题/帖子,但没有看到与 JWT 相关的帖子

下面是输出

System.ArgumentNullException:值不能为空。 (参数“值”) 在 System.Security.Claims.Claim..ctor(字符串类型,字符串值,字符串 valueType,字符串颁发者,字符串 originalIssuer,ClaimsIdentity 主题,字符串 propertyKey,字符串 propertyValue) 在 System.Security.Claims.Claim..ctor(字符串类型,字符串值) 在 /Users/Ken/Desktop/Coop_Marketing/Coop_Marketing/Coop_Marketing/Controllers/AccountController.cs:line 101 中的 Coop_Marketing.Controllers.AccountController.Login(LoginViewModel formdata) 在 Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.TaskOfIActionResultExecutor.Execute(IActionResultTypeMapper 映射器,ObjectMethodExecutor 执行器,对象控制器,对象 [] 参数) 在 Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.g__Awaited|12_0(ControllerActionInvoker 调用程序,ValueTask`1 actionResultValueTask) 在 Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.g__Awaited|10_0(ControllerActionInvoker 调用程序,任务 lastTask,下一个状态,作用域范围,对象状态,布尔 isCompleted) 在 Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed 上下文) 在 Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(状态&下一个,范围&范围,对象&状态,布尔& isCompleted) 在 Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.g__Awaited|13_0(ControllerActionInvoker 调用者,任务 lastTask,下一个状态,作用域范围,对象状态,布尔 isCompleted) 在 Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|24_0(ResourceInvoker 调用者,任务 lastTask,下一个状态,作用域范围,对象状态,布尔 isCompleted) 在 Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed 上下文) 在 Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(状态&下一个,范围&范围,对象&状态,布尔& isCompleted) 在 Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|19_0(ResourceInvoker 调用程序,任务 lastTask,下一个状态,作用域范围,对象状态,布尔 isCompleted) 在 Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|17_0(ResourceInvoker 调用程序,任务任务,IDisposable 范围) 在 Microsoft.AspNetCore.Routing.EndpointMiddleware.g__AwaitRequestTask|6_0(端点端点,任务 requestTask,ILogger 记录器) 在 Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext 上下文) 在 Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext 上下文)

下面是带有登录方式的Account控制器

   public async Task<IActionResult> Login([FromBody] LoginViewModel formdata)
    {
        // Get the User from database
         var user = await _userManager.FindByNameAsync(formdata.Username);

         var roles = await _userManager.GetRolesAsync(user);

        

        var key = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(_appSettings.Secret));
        double tokenExpiryTime = Convert.ToDouble(_appSettings.ExpireTime);

        if(user !=null && await _userManager.CheckPasswordAsync(user,formdata.Password))
        {

            
            var tokenhandler = new JwtSecurityTokenHandler();

            // Describe the token used by the user to log in

            var tokenDescriptor = new SecurityTokenDescriptor
                          
            {
               
                Subject = new ClaimsIdentity(new Claim[]
                {
                    
                    new Claim(JwtRegisteredClaimNames.Sub, formdata.Username),
                    new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
                    new Claim(ClaimTypes.NameIdentifier, user.Id),
                    new Claim(ClaimTypes.Role, roles.FirstOrDefault()),
                    new Claim("LoggedOn", DateTime.Now.ToString()),

                    
                }),
                

                SigningCredentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256Signature),
                Issuer = _appSettings.Site,
                Audience = _appSettings.Audience,
                Expires = DateTime.UtcNow.AddMinutes(tokenExpiryTime)
            };
            // Generate the token
            var token = tokenhandler.CreateToken(tokenDescriptor);
            return Ok(new {token= tokenhandler.WriteToken(token), expiration = token.ValidTo,username = user.UserName,userRole = roles.FirstOrDefault()});


        }

        
        // Return error
        ModelState.AddModelError("","Username/Password was not Found");
        return Unauthorized(new { LoginError = "Please check the Login Credentials - Invalid Username/Password was entered" });
    }
}

}

还有 LoginViewModel

public class LoginViewModel
{
    [Required]
    [Display(Name = "User Name")]

    public string Username { get; set; }

    [Required]
    [DataType(DataType.Password)]
    public string Password { get; set; }
} 

问题在于 > var tokenDescriptor = new SecurityTokenDescriptor 根据输出中提到的代码中的第 101 行。但是,我无法弄清楚为什么会出现错误。

【问题讨论】:

  • 错误显示 Claim 的构造函数有一个空参数 value...System.Security.Claims.Claim..ctor(String type, String value)。为了帮助调试,请将数组移出“单行新”嵌套,以便您可以逐步使用调试器并确定哪个声明失败。

标签: c# .net asp.net-mvc asp.net-core


【解决方案1】:

所以就像 Claim 有一个空参数。为此,您发现了这个问题。

更新您的代码如下:-

.....

 Subject = new ClaimsIdentity(new Claim[]
                {
                   
                    new Claim(JwtRegisteredClaimNames.NameId,formdata.UserName), //modified
                    new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
                    new Claim(JwtRegisteredClaimNames.Sub, user.Id.ToString()), //modified
                    new Claim(ClaimTypes.Role, roles.FirstOrDefault()),
                    new Claim("LoggedOn", DateTime.Now.ToString()),

                    
                }),

.....

希望它能解决您的问题。

【讨论】:

  • 是的,它确实解决了问题。非常感谢。
【解决方案2】:

在官方documentation中可以看到,当声明类型/值为空时,构造函数会抛出参数空异常。 因此,在创建 Claim 对象数组时,您似乎将空值传递给 Claim 构造函数。

正如@Jasen 所提到的,为了使调试更容易,更改单行声明数组的创建只是为了调试,并放置一个断点来确定哪个声明是罪魁祸首。

【讨论】:

    【解决方案3】:

    在官方documentation中可以看到,当声明类型/值为空时,构造函数会抛出参数空异常。因此,在创建 Claim 对象数组时,您似乎将空值传递给 Claim 构造函数。

    正如@Jasen 所提到的,为了使调试更容易,更改单行声明数组的创建只是为了调试,并放置一个断点来确定哪个声明是罪魁祸首。

    【讨论】:

      猜你喜欢
      • 2020-06-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-16
      • 2014-05-17
      • 2016-05-14
      相关资源
      最近更新 更多