【发布时间】:2020-09-08 02:25:43
【问题描述】:
我正在尝试在 .NET Core API 和 Angular 应用程序中调试 NullReferenceException,但我没有想法。
我正在尝试更新 User 的属性(“关于”部分)
在后端代码中,在AuthController 中,我有一个创建声明的登录方法,它似乎工作正常:
[HttpPost("login")]
public async Task<IActionResult> Login(LoginViewModel loginViewModel)
{
// login the user
var userFromRepo = await _authRepository.Login(loginViewModel.Email.ToLower(), loginViewModel.Password);
// check that user is logged in
if (userFromRepo == null)
return Unauthorized();
// create claims using user id and main email
var claims = new[]
{
new Claim(ClaimTypes.NameIdentifier, userFromRepo.Id),
new Claim(ClaimTypes.Name, userFromRepo.MainEmail),
new Claim(ClaimTypes.Name, userFromRepo.FirstName)
};
// generate key from secret token
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config.GetSection("AppSettings:Token").Value));
// generate hash and credentials
var cred = new SigningCredentials(key, SecurityAlgorithms.HmacSha512Signature);
// create token descriptions
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(claims),
Expires = DateTime.Now.AddDays(1),
SigningCredentials = cred
};
// instantiate token handler
var tokenHandler = new JwtSecurityTokenHandler();
// create token
var token = tokenHandler.CreateToken(tokenDescriptor);
// write token and return request
return Ok(new
{
token = tokenHandler.WriteToken(token),
});
}
然后我有一个更新用户属性的方法:
[HttpPut("{id}")]
public async Task<IActionResult> UpdateUser(string id, UserForUpdateDto userForUpdateDto)
{
// this is a check if user ID that is updating the profile matches the ID in the token
if (id != User.FindFirst(ClaimTypes.NameIdentifier).Value)
{
return Unauthorized();
}
var userFromRepo = await _doMoreRepo.GetUser(id);
userFromRepo.About = userForUpdateDto.About;
await _doMoreRepo.UpdateUser(id);
return NoContent();
}
在调试期间,我收到一条 500 错误消息
System.NullReferenceException:对象引用未设置为对象的实例
在代码行上:
User.FindFirst(ClaimTypes.NameIdentifier).Value
它在 Postman 中运行良好,所以我猜想我没有从 NameIdentifier 得到任何东西,但我不知道为什么?
我只是不知道该往哪里看。
我的前端 Angular 代码如下 - Login 将令牌添加到存储的方法:
login(model: any) {
return this.http.post(this.url + 'login', model)
.pipe(
map((response: any) => {
const user = response;
if (user) {
localStorage.setItem('token', user.token);
this.decodedToken = this.jwtHelper.decodeToken(user.token);
console.log('This is decoded token');
console.log(this.decodedToken);
}
})
);
}
更新配置文件方法:
updateProfile() {
this.userService.updateUser(this.authService.decodedToken.nameid, this.user).subscribe(next => {
this.alertify.success('Profile updated');
this.editForm.reset(this.user);
}, error => {
console.log(error);
this.alertify.error(error);
});
}
我查看了非常相似的问题here,所以我仔细检查了解决方案,但就我而言,我的app.module.ts 中确实包含tokenGetter()
export function tokenGetter() {
return localStorage.getItem('token');
}
和导入:
JwtModule.forRoot({
config: {
tokenGetter,
}
})
为了进一步调查它并确保我已经缩小到可能的问题区域,在我更换控制器时:
public async Task<IActionResult> UpdateUser(string id, UserForUpdateDto userForUpdateDto)
{
// this is a check if user ID that is updating the profile matches the ID in the token
if (id != User.FindFirst(ClaimTypes.NameIdentifier).Value)
{
return Unauthorized();
}
var userFromRepo = await _doMoreRepo.GetUser(id);
userFromRepo.About = userForUpdateDto.About;
await _doMoreRepo.UpdateUser(id);
return NoContent();
}
实际值如下:
public async Task<IActionResult> UpdateUser(string id, UserForUpdateDto userForUpdateDto)
{
if (id != "user ID value")
{
return Unauthorized();
}
var userFromRepo = await _doMoreRepo.GetUser(id);
userFromRepo.About = userForUpdateDto.About;
await _doMoreRepo.UpdateUser(id);
return NoContent();
}
这工作正常,没有任何错误,并且属性更新正常。
我错过了什么?
编辑:
这是我发出http.put 请求的updateUser() 方法:
updateUser(id: string, user: User) {
// console.log('user ID is: ' + id);
// console.log('User object passed to updateUser() is: ');
// console.log(user);
return this.http.put(this.baseUrl + 'user/' + id, user);
}
点击后端UserController.cs中的UpdateUser()。
【问题讨论】:
-
如果
User.FindFirst返回null,使用.Value会抛出。您还没有发布实际的请求,所以只能猜测这两个请求是不同的。您可以使用例如 Fiddler 或开发人员工具中浏览器的网络选项卡来检查实际发送到服务器的内容。我怀疑 Angular 请求缺少身份验证标头或 cookie,因此UpdateUser匿名运行,这意味着没有当前用户 -
@PanagiotisKanavos,感谢您的评论和有用的信息,我想您可能会有所收获。我将尝试对此进行调查并报告。再次感谢您抽出宝贵时间提供帮助。
标签: c# asp.net angular typescript