Enhance user security with password updates in ASP.NET Core 6 and Angular

I am having trouble updating passwords for users through the API. It works fine when done directly, but not through Angular UI in my project that utilizes ASP.NET Core 6 Web API and Angular 13.

Here is the code for the ASP.NET Core Web API:

[HttpPut]
[Route("Change-password")]
public async Task<IActionResult> ChangePassword([FromBody] ChangePassword model)
{
    var user = await userManager.FindByEmailAsync(model.Email);

    if (user == null)
    {
        return StatusCode(StatusCodes.Status404NotFound, new Response { Status = "Error", Message = "User does not exist" });
    }

    if (string.Compare(model.NewPassword, model.ConfirmNewPassword) != 0)
    {
        return StatusCode(StatusCodes.Status404NotFound, new Response { Status = "Error", Message = "The new password and confirm new password do not match" });
    }

    var result = await userManager.ChangePasswordAsync(user, model.CurrentPassword, model.NewPassword);

    if (result.Succeeded)
    {
       var errors = new List<string>();

       foreach (var error in result.Errors)
       {
           errors.Add(error.Description);
       }
                
       return StatusCode(StatusCodes.Status500InternalServerError, new Response { Status = "Success", Message = "Password changed successfully" });
     }

     return Ok(new Response { Status = "Error", Message = "Current password is incorrect" });
}

This is the HTML markup:

<form #passwordUpdateForm="ngForm" (ngSubmit)="updatePassword(passwordUpdateForm)" class="col-md-4 mt-3">
    <div *ngIf="!!password_update_msg" [ngClass]="has_error ? 'alert alert-danger': 'alert alert-info'">{{password_update_msg}}</div>
    <div class="row">
        <mat-form-field class="col-sm-12">
            <input matInput name="oldPassword" ngModel placeholder="Old Password" [type]="ohide ? 'password' : 'text'" required>
                <mat-icon matSuffix (click)="ohide = !ohide">{{ohide ? 'visibility_off' : 'visibility'}}</mat-icon>
         </mat-form-field>
     </div>

     <div class="row">
         <mat-form-field class="col-sm-12">
             <input matInput name="newPassword" ngModel placeholder="New Password" [type]="nhide ? 'password' : 'text'" required>
             <mat-icon matSuffix (click)="nhide = !nhide">{{nhide ? 'visibility_off' : 'visibility'}}</mat-icon>
         </mat-form-field>
     </div>

     <div class="row">
         <mat-form-field class="col-sm-12">
             <input matInput name="reNewPassword" ngModel placeholder="Confirm New Password" [type]="rnhide ? 'password' : 'text'" required validateEqual="newPassword" #reNewPassword="ngModel">
             <mat-icon matSuffix (click)="rnhide = !rnhide">{{rnhide ? 'visibility_off' : 'visibility'}}</mat-icon>
         </mat-form-field>
     </div>

     <button class="mt-4 btn-block" type="submit" mat-raised-button color="primary" [disabled]="passwordUpdateForm.invalid">Change Password</button>
</form>

The corresponding service code in Service.ts file:

UpdatePassword(oldPassword: string, newPassword: string): Observable<any> {
const body = new FormData();
body.append('oldPassword', oldPassword);
body.append('newPassword', newPassword);
return this.http.put<any>(this.baseUrl+'/Change-password', body )
     .pipe(catchError(this.errorHandler));
    }

And here is the TypeScript (Ts) code:

updatePassword(form: any) {
    const oldPassword = form.value.oldPassword;
    const newPassword = form.value.newPassword;
    const reNewPassword = form.value.reNewPassword;

    if (newPassword !== reNewPassword) {
      this.has_error = true;
      this.password_update_msg = 'New Password and Confirm Password must be same';
      return;
    }

    this.userService.UpdatePassword(oldPassword, newPassword)
      .subscribe(() => {
        this.has_error = false;
        this.password_update_msg = 'Password Update Successful, Please Logout and Re Login !!!';
        form.reset();
      },
        () => {
          this.has_error = true;
          this.password_update_msg = 'Password Update Failed !!!';
        });
  }

However, I encounter an error:

Unsupported Media Type 415

Any assistance on resolving this issue would be greatly appreciated.

Answer №1

Tip: Sending object in request body

If your API endpoint for ChangePassword expects the object in the request body with the [FromBody] attribute:

public async Task<IActionResult> ChangePassword([FromBody] ChangePassword model)

In your front-end code, you can send the object as part of the request body like this:

updatePassword(oldPw:string,newPw:string): Observable<any>{
  let body = {
    oldPassword: oldPw,
    newPassword: newPw
  };

  return this.http.put<any>(this.base+'/Change-pwd', body )
     .pipe(catchError(this.errorHandler));
}

Tip: Sending object as form data

Alternatively, if you need to send the object as form data, use the [FromForm] attribute instead of [FromBody] in the API method.

public async Task<IActionResult> ChangePassword([FromForm] ChangePassword model)

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

Wait for Protractor until the page has completely finished loading

After navigating to https://docs.angularjs.org/tutorial, I attempted to click on '0 - Bootstrapping' under Tutorial but Protractor did not wait for the page to fully load, resulting in an Error. Error: Failed to execute 'click' on &a ...

Modify the appearance of certain text within an input field

I need some help adding style to specific text within an input field. For example, if the user types in "Hello world" and the special text is "world" I want to achieve this result: https://i.sstatic.net/Ozd6n.png This is what my HTML code looks like: & ...

Angular 7: Retrieve the most recent subscription response from an array of observables

Scenario: I am handling multiple POST requests to update a single table with diverse data sets. The response from the request will contain the updated table data. To streamline this process, I stored the observables in an array and employed forkJoin to co ...

Error TS2339 occurs when attempting to migrate to TypeScript due to the absence of the 'PropTypes' property on the 'React' type

Currently in the process of converting a javascript/react project to a typescript/react/redux project. Encountering an issue with this particular file: import React from 'react'; import GoldenLayout from 'golden-layout'; import {Provi ...

Transferring information between screens in Ionic Framework 2

I'm a beginner in the world of Ionic and I've encountered an issue with my code. In my restaurant.html page, I have a list of restaurants that, when clicked, should display the full details on another page. However, it seems that the details for ...

Decipher and comprehend the buttons listed in the language translation document

Looking for assistance with a pipe issue. I've created the following custom SafeHtmlPipe: import { DomSanitizer } from '@angular/platform-browser'; import { Pipe, PipeTransform, SecurityContext } from '@angular/core'; @Pipe({ nam ...

Utilizing the arr.push() method to replace an existing value within an array with a new object, rather than simply adding a new

Seeking help to dynamically render a list of components that should expand or shrink based on values being added or removed from an array of custom objects. However, facing an issue where pushing a value into the array only replaces the previous value inst ...

Is there a way to link the data from datepicker JS to Angular?

I am attempting to integrate the two files below into my Angular project: <script src='https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.6.4/js/bootstrap-datepicker.min.js'></script> <script src='https://cdnjs.clou ...

Troubles arising while using ng serve in Angular 2

I'm currently facing an issue during the installation process of an existing Angular application. When trying to run the application using the ng serve command, I encounter the following error message: The "@angular/compiler-cli" package was not prope ...

Typescript fails to recognize that props are passed by react-navigation through withNavigation HOC

I am encountering an issue with a specific package setup: "react-navigation": "2.18.2", "@types/react-navigation": "2.13.0", "typescript": "3.1.6", The problem arises when attempting to utilize the withNavigation higher-order component in a child compone ...

How can TypeScript be forced to output a specific data type?

I've created a generic "fetcher" function that is designed to handle different types of entities. However, I'm encountering an issue where TypeScript is inferring the return type based on all possible conditions within the function. Is there a w ...

Is it possible to modify the chart type in amCharts by selecting an option from a dropdown

Imagine I have a Pie chart already loaded and I need the user to switch it to a Line chart or any other type from a dropdown menu. Is there a way to do this in amCharts? I've seen it done in HighCharts, but I'm struggling to find a solution for a ...

Exploring the use of Observables in Angular 2 services

Ensuring the seamless transfer of data between components is crucial in Angular development. One common way to achieve this is by utilizing observables. Let's take a look at how observables are implemented in a service: import { Injectable } from &ap ...

After making a request with HttpClient, the response can either be an empty body or a body

Encountering issues with HttpClient while trying to post data, I am faced with two distinct errors: When booking is treated as an object, the error message reads: Backend returned code 400, body was: [object Object]. Converting booking to JSON format by ...

Arranging JSON elements according to a separate array in Angular 2 or Node.js

Looking for a solution with optimal performance, I am seeking to achieve the rearrangement of a list using either Angular2 or NodeJS. My input consists of user fruit preferences' IDs {15, 43, 55, 67, 98}; In addition, I have a JSON object containin ...

Saving the contents of a book in an Ionic mobile application

I'm working on an app that features an e-reader function for users to read a single book. Where should I save the text data for the book? I experimented with storing pages as .json files in the assets folder but ran into issues. The path to the asset ...

Sorting with lodash in Angular 2

Section: import { Component, OnInit } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import * as _ from 'lodash'; @Component({ selector: 'app-ore-table', templateUrl: './ore-table ...

Menu: animated opening/closingIs this convenient, or

How can I add animation to opening and closing menu items in my project? I am not sure if it can be done in Angular or CSS. I have provided a reproduction of the project for reference => Stackblitz. HTML file <div class="wrapper"> & ...

Activating functions based on radio button selection in React with TypeScript

Below are the radio buttons with their respective functions: <div className="row"> <div className="col-md-4"> <label className="radio"> <input onChange={() => {serviceCalc()}} ty ...

Unit Testing Angular: Passing FormGroupDirective into a Function

I am currently writing unit tests for a function that takes a parameter of type FormGroupDirective. I have been able to test most of the logic, but I'm unsure about what to pass as a parameter when calling the resetForm() function. Here is the code sn ...