Why does Angular throw a NullReferenceException when calling User.FindFirst(ClaimTypes.NameIdentifier), whereas Postman executes the same code without any

I'm currently troubleshooting a NullReferenceException in a .NET Core API and Angular application, but I've hit a roadblock.

The specific issue arises when trying to update the "About" section of a User.

Take a look at the text area screenshot for reference

Within the backend code, specifically in the AuthController, the Login method is responsible for creating claims and appears to be functioning correctly:

[HttpPost("login")]
public async Task<IActionResult> Login(LoginViewModel loginViewModel)
{
        // User login process
        var userFromRepo = await _authRepository.Login(loginViewModel.Email.ToLower(), loginViewModel.Password);

        // Ensure user is logged in
        if (userFromRepo == null)
            return Unauthorized();

        // Generate 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)
        };

        // Create 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);

        // Define token properties
        var tokenDescriptor = new SecurityTokenDescriptor
        {
            Subject = new ClaimsIdentity(claims),
            Expires = DateTime.Now.AddDays(1),
            SigningCredentials = cred
        };

        // Initialize token handler
        var tokenHandler = new JwtSecurityTokenHandler();

        // Create token
        var token = tokenHandler.CreateToken(tokenDescriptor);

        // Emit token and respond to request
        return Ok(new
        {
            token = tokenHandler.WriteToken(token),
        });
}

There's also a method designed to modify a User property:

[HttpPut("{id}")]
public async Task<IActionResult> UpdateUser(string id, UserForUpdateDto userForUpdateDto)
{
    // Validate if the user ID 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();
}

While debugging, a 500 error occurs with the message:

System.NullReferenceException: Object reference not set to an instance of an object

This error originates in the line of code:

User.FindFirst(ClaimTypes.NameIdentifier).Value

Everything works as expected in Postman, leading me to suspect that I'm not fetching anything from NameIdentifier, but I can't pinpoint why?

I'm running out of places to investigate further. Help!

In my Angular front end code, you'll find the following - the Login method adds the token to storage upon authentication:

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);
      }
    })
  );
}

Profile update function:

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);
    });
}

An issue on Stack Overflow was similarhere. I revisited the solution but it seems that my tokenGetter() is included in my app.module.ts:

export function tokenGetter() {
   return localStorage.getItem('token');
}

along with the import:

 JwtModule.forRoot({
     config: {
        tokenGetter,
     }
  })

To narrow down the problem area, I replaced the code snippet:

public async IActionResult UpdateUser(string id, UserForUpdateDto userForUpdateDto)
{
    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();
}

with a hardcoded value like this:

public async 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();
}

The hardcoded value approach works smoothly without any errors, successfully updating the property.

What could I possibly be overlooking?

EDIT:

Here's my updateUser() method where the http.put request is carried out:

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);

}

This contacts the UpdateUser() function in the UserController.cs on the backend.

Answer №1

After consulting the insights shared by Panagiotis Kanavos, I delved deeper into the issue and discovered that the request was missing the crucial authentication header.

As my application utilizes the JwtModule:

export function tokenGetter() {
   return localStorage.getItem('token');
}
 JwtModule.forRoot({
     config: {
        tokenGetter,
     }
  })

I initially assumed that my token would be automatically included in the headers without the need for manual intervention.

The oversight on my part was neglecting to include the correct whitelistedDomains options within the configuration of the JwtModule, which ultimately led to its absence from the request header.

The remedy involved whitelisting the appropriate domains as follows:

JwtModule.forRoot({
         config: {
            tokenGetter: tokenGetter,
            whitelistedDomains: ['localhost:5000', 'localhost:5001'],
            blacklistedRoutes: ['localhost:5000/auth']
         }
      })

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Establishing the placement of map markers in Angular

Currently, I am in the process of developing a simple web application. The main functionality involves retrieving latitude and longitude data from my MongoDB database and displaying markers on a map, which is functioning correctly. However, the issue I&apo ...

Error Alert: Redundant Identifier in Angular 2 TypeScript Documents

After following the Angular2 TS Quickstart guide, I noticed duplicate files scattered across various folders in my project. For browser: typings/browser node_modules/angular2/typings/browser Regarding es6-shim: node_modules/angular2/typings/es6-shi ...

I seem to have hit a roadblock today and are unable to code beyond what the progress bar

I'm currently facing a challenge with a progress bar while working on a custom backup utility. The functionality allows users to force an update immediately upon clicking a button. Once the button is clicked, it triggers a console application that run ...

Learn how Angular 2 allows you to easily add multiple classes using the [class.className] binding

One way to add a single class is by using this syntax: [class.loading-state]="loading" But what if you want to add multiple classes? For example, if loading is true, you want to add the classes "loading-state" and "my-class". Is there a way to achieve t ...

Implementing child components in React using TypeScript and passing them as props

Is it possible to append content to a parent component in React by passing it through props? For example: function MyComponent(props: IMyProps) { return ( {<props.parent>}{myStuff}{</props.parent>} } Would it be feasible to use the new compone ...

Converting dates in JavaScript to the format (d MMMMM yyyy HH:mm am) without using moment.js

Looking to convert the date "2020-02-07T16:13:38.22" to the format "d MMMMM yyyy HH:mm a" without relying on moment.js. Here is one method being utilized: const options = { day: "numeric", month: "long", year: "numeric", } var date1 = new Date ...

The srcSet functionality in the Image component seems to be malfunctioning in the next.js framework, as it is failing to display

Check out my Next.js code snippet below: import React from "react"; import style from "@/styles/Home.module.css"; import Image from "next/image"; function index() { return ( <> <div className="contai ...

What is the best way to provide JSON data in Angular?

I am working on an Angular 4 application that is using Webpack, and I am currently facing a challenge with serving a JSON file. I have two main questions regarding this: When the JSON file is static, I am struggling to configure Webpack to handle it the ...

Validators in Angular forms are a powerful tool for enforcing

Is it possible to use Validators in the ts.file to display an error message when a field is invalid, rather than directly in the html? Thanks. html <form [formGroup]="form"> <mat-form-field> <mat-label>Nom</mat-label> ...

Issue with C# Binding XML Element to Class not Resolved

In the XML provided below, there seems to be an issue with the class structure. Although all other elements are getting bound properly, the 'bed_groups' element is not. Here is the XML and the class structure: public class AvailabilityResponse ...

Chrome Devtool reported an error, but the majority of them are in a null file

Currently grappling with an irksome problem in Vue.js. No matter how hard I try, I just can't seem to pinpoint the error. Even when setting a debugger, all it shows is an empty file. Please take a look at the image provided. Any assistance on identify ...

Experiencing difficulty when trying to link control with form in Angular Reactive forms

I am currently working on Angular Reactive forms and facing an issue with binding form controls dynamically. Initially, I have a form array in form group, and then I push form groups into the form array to add form controls dynamically. However, I encounte ...

How to keep your .NET SmtpClient password safe

Is my password secure if I utilize System.Net.Mail and SmtpClient following the guidelines provided by ScottGu in this blog post here? I am aware of potential security concerns related to storing passwords in plain text on the server, but my primary conc ...

Encountered an unexpected token error when executing karma-coverage in a project using TypeScript

I have been working on a simple Angular/Typescript project that includes 12 basic unit tests which all pass successfully. However, I am now looking to measure the code coverage of these tests. Despite trying different methods, I have not been able to achie ...

Create a unified web deployment package by combining various web projects

I currently have a large number of web projects (80+) that I deploy using WDP. For each project, I create a web deploy package and then publish it to the environments. However, this process is slow as each package is deployed without deleting existing file ...

A generic type in TypeScript that allows for partial types to be specified

My goal is to create a type that combines explicit properties with a generic type, where the explicit properties have priority in case of matching keys. I've tried implementing this but encountered an error on a specific line - can anyone clarify why ...

Incorporate personalized No Data Available message in ngx-datatable

How can I customize the no data message for ngx-datatable? I want to avoid displaying the default message that comes with it. Here is what I have attempted so far: <div *ngIf="showTable"> <ngx-datatable [rows]="rows"> ...

Utilizing the Double Mapping Feature in React with Typescript

It seems I might be overlooking something, can someone guide me on how to properly double map in this scenario? I'm encountering an error on the second map: Property 'map' does not exist on type '{ departure: { code: string; name: strin ...

Modal for Firestore CRUD operations update()

Currently seeking assistance with a CRUD system that involves modal dialogues. I have successfully implemented adding and deleting functionalities, but I am encountering an issue with editing. Although I can retrieve the data for each record in its respect ...

Is there a way to transfer data to a different component in React without relying on a hierarchical parent-child relationship?

I am struggling to pass the data from the "SearchingData" Component to the "Search" Component. The SearchingData component is a child of the Search component. I need to transfer the data from the variable named "datacame" to the Search Component. Can som ...