Categories
API ASP.NET Development MVC

Getting CORS error in Angular 8 while trying to post data to Asp.net core web api

I am making CRUD using Angular 8 and Asp.net core.
Everything works fine until I submit data.

It returns me following error.

Access to XMLHttpRequest at ‘http://localhost:56975/api/PaymentDetail‘ from origin ‘http://localhost:4200‘ has been blocked by CORS policy: Request header field content-type is not allowed by Access-Control-Allow-Headers in preflight response.

I already add Microsoft.AspNetCore.Cors package.

This is my controller API Method.

    // POST: api/PaymentDetails
    [HttpPost]
    public async Task<IActionResult> PostPaymentDetail([FromBody] PaymentDetail paymentDetail)
    {           
        _context.PaymentDetails.Add(paymentDetail);
        await _context.SaveChangesAsync();

        return CreatedAtAction("GetPaymentDetail", new { id = paymentDetail.PMId }, paymentDetail);
    }    

This is my Angular service code.

import { Injectable } from '@angular/core';
import { PaymentDetail } from './payment-detail.model';
import { HttpClient } from '@angular/common/http';

@Injectable({
  providedIn: 'root'
})
export class PaymentDetailService {
  formData: PaymentDetail;
  readonly rootURL = 'http://localhost:56975/api';
  constructor(private http: HttpClient) { }

  postPaymentDetail(formData: PaymentDetail) {
    return this.http.post(this.rootURL + '/PaymentDetail', formData);
  }
}       

This is my component code.

<form #form="ngForm" autocomplete="off" (submit)="onSubmit(form)">
    <input type="hidden" name="PMId" [value]="service.formData.PMId">
    <div class="form-group">
            <div class="input-group">
                <div class="input-group-prepend">
                    <div class="input-group-text bg-white">
                        <i class="fas fa-user-circle" [class.green-icon]="CardOwnerName.valid" [class.red-icon]="CardOwnerName.invalid && CardOwnerName.touched"></i>
                    </div>
                </div>
                <input name="CardOwnerName" #CardOwnerName="ngModel" [(ngModel)]="service.formData.CardOwnerName" class="form-control"
                placeholder="Card Owner Name" required >
            </div>
    </div>
    <div class="form-group">
            <div class="input-group">
                <div class="input-group-prepend">
                    <div class="input-group-text bg-white">
                        <i class="far fa-credit-card" [class.green-icon]="CardNumber.valid" [class.red-icon]="CardNumber.invalid && CardNumber.touched"></i>
                    </div>
                </div>
                <input name="CardNumber" #CardNumber="ngModel" [(ngModel)]="service.formData.CardNumber" class="form-control"
                placeholder="16 Digit Card Number"  maxlength="16" minlength="16" required>
            </div>
    </div>
    <div class="form-row">
    <div class="form-group col-md-7">
            <div class="input-group">
                <div class="input-group-prepend">
                    <div class="input-group-text bg-white">
                        <i class="fas fa-calendar-alt" [class.green-icon]="ExpirationDate.valid" [class.red-icon]="ExpirationDate.invalid && ExpirationDate.touched"></i>
                    </div>
                </div>
                <input name="ExpirationDate" #ExpirationDate="ngModel" [(ngModel)]="service.formData.ExpirationDate" class="form-control"
                placeholder="MM/YY" required maxlength="5" minlength="5">
            </div>
    </div>
    <div class="form-group col-md-5">
            <div class="input-group">
                <div class="input-group-prepend">
                    <div class="input-group-text bg-white">
                        <i class="fas fa-key" [class.green-icon]="CVV.valid" [class.red-icon]="CVV.invalid && CVV.touched"></i>
                    </div>
                </div>
                <input type="password" name="CVV" #CVV="ngModel" [(ngModel)]="service.formData.CVV" class="form-control"
                placeholder="CVV" required minlength="3" maxlength="3">
            </div>
    </div>
</div>
    <div class="form-group">
        <button type="submit" [disabled]="form.invalid" class="btn btn-success btn-lg btn-block"><i class="fas fa-database"></i> Submit </button>
    </div>
</form>

This is my .ts file code.

import { Component, OnInit } from '@angular/core';
import { PaymentDetailService } from 'src/app/shared/payment-detail.service';
import { NgForm } from '@angular/forms';

@Component({
  selector: 'app-payment-detail',
  templateUrl: './payment-detail.component.html',
  styles: []
})
export class PaymentDetailComponent implements OnInit {

  constructor(private service: PaymentDetailService) { }

  ngOnInit() {
    this.resetForm();
  }

  resetForm(form?: NgForm) {
    if (form != null) {
      form.resetForm();
    }
    this.service.formData = {
      PMId: 0,
      CardOwnerName: '',
      CardNumber: '',
      ExpirationDate: '',
      CVV: ''
    };
  }

  onSubmit(form: NgForm)  {
    this.service.postPaymentDetail(form.value).subscribe(
      res => {
        this.resetForm(form);
      },
      err => {
        console.log(err);
      }
    )
  }

}

This is my startup.cs code.

using App1.Models;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json.Serialization;

namespace App1
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            //services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1)
                .AddJsonOptions(options =>
                {
                    var resolver = options.SerializerSettings.ContractResolver;
                    if (resolver != null)
                        (resolver as DefaultContractResolver).NamingStrategy = null;
                });

            services.AddDbContext<PaymentDetailContext>(options =>
            options.UseSqlServer(Configuration.GetConnectionString("DevConnection")));

            services.AddCors();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseCors(options =>
            options.WithOrigins("http://localhost:4200/")
            .AllowAnyMethod()
            .AllowAnyHeader());

            app.UseMvc();
        }
    }
}

please help!

Leave a Reply

Your email address will not be published. Required fields are marked *