In this article, we’ll implement Asp.Net Core 5.0 Web API CRUD Operations with Angular 11. To demonstrate the topic, we’ll build a project from scratch with payment details like credit/ debit card.
GitHub repository: https://bit.ly/3qyiusO
Sub-topics discussed.
- ASP.NET Core Web API
- Create .NET Core Web API
- Setup Database with EF Core
- API Controller for CRUD Web Methods
- Enable CORS for Angular App
- Angular Client Side
- Create Angular 11 Project
- Consume ASP.NET Core API From Angular
- Form Design and Validation
- Insert/ Create Record by Form Submission
- Retrieve and Display Inserted Records
- Update and Delete Operation
Create ASP.NET Core Web API
In Visual Studio 2019, From the new project window, select Asp.Net Core Web Application.
Once you provide the project name and location. A new window will be opened as follows, Select API. The above steps will create a brand new ASP.NET Core Web API project.
Setup Database
Let’s create a Database for this project. Inside this project, we’ll be using Entity Framework Core to create and interact with the database. So first of all we’ve to install corresponding NuGet packages. Right-click on the project name from Solution Explorer, click on Manage NuGet Packages, from Browse Tab, install the following 3 packages with same version as that of Asp.Net Core.
Now, let’s define DB model class file –PaymentDetail.cs
in a new folder Models
.
Now let’s define DbContext
class file- /Models/PaymentDetailContext.cs
.
DbContext class- PaymentDetailContext
decides what should be added to actual physical database during DB Migration. So we have added DbSet
property for PaymentDetail
Model class, after migration PaymentDetails
table will be created in SQL Server Database.
Into this model class constructor parameter- options
, we have to pass which DbProvider (SQL Server, MySQL, PostgreSQL, etc) to use and corresponding DB connection string also. For that, we’ll be using dependency injection in ASP.NET Core with Startup.cs
file as follows.
Here we’ve used dependency injection for DbContext
class, through which SQL Server is set as a DbProvider with a connection string, Now save the connection string in appsettings.json
file using DevConnection
key as follows.
Now let’s do the migration. Select project from solution explorer, then go to Tools > NuGet Package Manager > Package Manager Console. Then execute following commands one by one.
Add-Migration "InitialCreate"
Update-Database
After successful migration, as per the connection string, a new database – PaymentDetailDB
will be created with PaymentDetails
table. Also, there will be a new Migrations
folder created with corresponding C# files.
Create API Controller for CRUD Operations
To create a new API controller, right-click on Controllers folder Add > Controller, Select API Controller with actions, using Entity Framework
.
With the help of scaffolding mechanism, newly created PaymentDetailController
will look like this.
It contains web methods POST, GET, PUT and DELETE for Create, Retrieve, Update and Delete operations respectively. As a constructor parameter we’ve context
of the type PaymentDetailContext
. the instance/value for this parameter will be passed from dependency injection from StartUp
class.
For this project, we don’t have to change anything in web methods and you can test any of these CRUD operations using software like postman or you use open api support with the swagger interface.
Create Angular App
Now let’s create front-end client-side app in Angular 11. For that execute following Angular-CLI commands one by one.
ng new app_name
# after project creation.
# navigate inside project folder
cd app_name
# open in vs code
code .
# from vs code terminal
# command to open the app in default web browser
ng serve --o
Before moving forward, let’s look at the structure of the app that we want to build.
● src
+---● app
| +--● payment-details
| | |--payment-details.component.ts|.html
| | |
| | +--● payment-detail-form
| | |--payment-detail-form.component.ts|.html
| |
| +--● shared
| | |--payment-detail.service.ts
| | |--payment-detail.model.ts
| |
| |--app.module.ts
|
|--index.html (cdn path for bootstrap & fa icons)
We’ve two components, list of records will be shown in payment-details
component, it has a child component payment-detail-form
, inside that, a form for insert and update operation can be designed.
To create these 2 components, you can execute the following commands.
ng g c payment-details -s --skipTests
ng g c payment-details/payment-detail-form -s --skipTests
Options usedinlinestyle | -s
: skip seperate component specific stylesheet---skipTests
: skip test files with extension .spec.ts
Now let’s replace the default component file- app.component.html
as follows.
To show list of records and it’s form side by side, update payment-details.component.html
as bellow.
For this app development, we’ll be using Bootstrap and Font Awesome Icons. so let’s add their stylesheet reference in index.html.
I’ve few custom CSS to add in global style sheet – styles.css
.
.form-group label {
color: grey;
}
.form-group input {
font-weight: 500;
}
.form-group input::placeholder {
color: #c0bdbd;
font-weight: 300;
}
thead th{
font-weight: 400;
}
table tr:hover {
background-color: #fffbf2;
cursor: pointer;
}
/*for invalid form controls*/
input.invalid {
border-color: red;
}
How to Consume .Net Core API from Angular
First of all, let’s create a model class for payment details – shared/payment-detail.model.ts
. You could manually create the file with the following CLI command.
ng g class shared/payment-detail --type=model --skipTests
# there is no seperat command for model
# hence we use class creation command with type option
# type is used to name the file like '.model.ts'
Update the model class with corresponding properties similar to .Net Core API model properties.
Now let’s create a service class to interact with ASP.NET Core Web API- shared/payment-detail.service.ts
. Here is the CLI command to create the service class.
ng g s shared/payment-detail --skipTests
Update the service class as below.
formData
property can be used for designing the form for CRUD Operations, list
array is used to store all of the records from the API. baseURL
contains the base URL for the Web API controller. Now let’s run the API from Visual Studio – Debug > Start Debugging(F5). HttpClient
is used to make HTTP request to the server. Along with methods for CRUD operations, we’ve refreshList
function to populate existing records into list
property.
To use HttpClient
, we also need to import HttpClientModule
. So update app/app.module.ts
as follows.
Form Design and Validation
Now let’s design the form in payment-detail-form
component.
Since we’ve the service injected here. we can access it’s property formData
in component HTML file for designing the form. resetForm
function will reset the form to its initiale state.
As a first step towards designing the form, we’ve to import FormsModule
in app/app.module.ts
.
Now let’s design the form. so update payment-detail-form.component.html
as shown below.
The above code snippet might be confusing for you because here we’ve put everything related to the form design and form validation. we have input fields for all model properties including paymentDetailId
(hidden field). Each of the input field is bound to its respective property through 2 way data-binding.
Inside this form, all field has the required validation and number of characters is restricted to all field except CardOwnerName
. While validating Angular form fields, we can use auto-generated classes/attributes for showing validation error indications. Auto-generated classes/attributes by Angular.
ng-invalid (class) orinvalid (property) | X | ng-valid (class) orvalid (property) |
ng-untouched (class) oruntouched (property) | X | ng-touched (class) ortouched (property) |
To indicate validation error, we conditionally applied CSS class – invalid
using the above properties invalid
and touched
. Finally, the submit button is conditionally disabled based on whether the form as a whole is valid or not.
Currently our Angular Form in payment-detail-form
component looks like this.
Insert a new Record
let’s implement submit event for the form.
Now define the function – onSubmit
inside payment-detail-form.component.ts
.
A separate function insertRecord
is defined to insert a new record into the SQL server table.
Before testing this operation, we have to Enable CORS in Asp.Net Core API, .Net Core Web API will block request from another application which is hosted in another domain or in another port number. by default, Angular is running at port number 4200 and Web API is hosted at a different port number. to make Http Request, we’ve to Enable-CORS (Cross Origin Resource Sharing) in Web API for the port 4200.
You just need to update Startup
class like this.
Inside the Configure function, it is better to keep the function call UseCors
before any other lines. Now you can try the insert operation. for me, it is working fine. Comment if you face any problem.
Retrieve and Display all Inserted Records
Inserted records can be retrieved and displayed in payment-details component, for that let’s update the component typescript file as follows.
Inside list component ngOnInit
lifecycle hook, we’ve called refreshList
function to populate list
array in service class. using service list
property, we can render all of the inserted records in payment-details component html. So update the table div
as follow.
Update and Delete Operation
To implement update operation, we’ve added click event for all td
cells as shown below.
Inside the click event function, we have to populate the corresponding selected record inside the form. so add the following function to payment-details component.
Inside the function, we just updated the selected record object into formData
property in service class. since the form is bound to formData
properties, the form field will get populated with corresponding details.
After making required changes in these populated value fields, user can submit the form for the update operation. so we have to handle both insert and update operation inside the same form submit event in payment-detail-form component. hence update the payment-detail-form.component.ts
.
Inside the form, we have a hidden field for paymentDetailId
. Based on its value in submit function, we can decide whether we’ve got an insert/ update operation. insertRecord
is already defined. with updateRecord
function, we will update the corresponding payment-detail record.
Now let’s implement Delete Operation in parent list component. For that add delete button inside that table rows.
update payment-details.component.html as shown below.
Now lets define onDelete
function in payment-details.component.ts.
So that’s all about Angular CRUD operations with ASP.NET Core Web API.
Video Tutorial
In our YouTube channel, we’ve covered the same topic you could watch the same from here.
Great article!
Though I am not able to insert values. When I click on submit, the values aren’t being inserted and not being displayed.
Update & delete is working properly. Kindly help ASAP!
How to receive API Call success or failure from Angular subscribe?
Thank you so much for this tutorial, but I have a small problem that can’t be solve, hope you can answer me , after step “Retrieve & Display records from Web API with Angular ” ,the list I get from db not showing up, the only thing appear is number of datas in my db, (like: I have 5 id in db, my local only show 5 rows without any datas showing up, i dont know why and still cant fix it
after clicking on submit (after the CORS step) couldnt get the data in db and the console shows
“Cannot read property ‘toLowerCase’ of undefined” error.
good day Code Affection – am really enjoying your videos, but recently i was busy implementing this video…but below is the error am getting when i try to update database. please help me sir.
“A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: Named Pipes Provider, error: 40 – Could not open a connection to SQL Server)”
Check and test your Sql connection. After that, open appsettings.json and set the the Connection strings to your server name
Getting the following issue:
No ‘Access-Control-Allow-Origin’ header is present on the requested resource.
I’m using the Cors information that you provided above. Any idea what’s happening here?
This error might not be related to the CORS configuration. Please run and test the API in debug mode with breakpoints.
If you can’t find any error there. let me know.
Still can’t seem to find the error. API seems to be running just fine.
Still can’t seem to find an error. Do you know what else could be causing the issue?
Could you ping me at shamseer@codaffection.com
It’s all good except using toatsr for notification, replace this.toastr.info by console.log in update function. Thanks for the article.
What will be the form path I need to use.
Thanks
Get method in angular is not displaying the data. Can you please help me .
Why data is not displaying. Get method is not working in angular . Can you please help me .
Post method is working in api and angular .
I got to this point in the “Insert a New Record” section: “Now you can try the insert operation. for me, it is working fine.”
The form looks OK and I can enter values into the text boxes, but no matter what I add to the text boxes the “Submit” button remains unavailable.
Check whether form controls are valid or not.
Hi Shamseer,
Does your get method works correctly ?
Need code ..how can i get it
core.js:4197 ERROR TypeError: Cannot read property ‘CardOwnerName’ of undefined
Fixed. Initialize formData in service with a new instance.
Try putting the c in lower case like -> ‘cardOwnerName’ in your html file wherever it is showing this error. Hope this solves your error
I am not able to insert the record.
net::ERR_CONNECTION_RESET,I am getting unknown error.
How to resolve?
Yes! Thank you! What I need!
Article très intéressant et instructif
src/app/payment-details/payment-detail/payment-detail.component.html:3:47 – error TS2341: Property ‘service’ is private and only accessible within class ‘PaymentDetailComponent’.
Please help me
It should be pubilc instead of private
Put not found 404 error please help me?
Please tell me if i insert one new record then list show two records why?
Please tell me about put method if i edit new record then 404 error occur on console that PUT not found please help me?
Please tell me if i insert one record list show two why?
Im getting this error at the console . ERROR TypeError: Cannot read property ‘formData’ of undefined
at Object.eval
That is a wonderful example. But got error while i submit. But even before submit it is showing me
reload.js:22 WebSocket connection to ‘ws://127.0.0.1:5500//ws’ failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED
on chrome and
no error on edge console and simply freezes/no response during submit.
I have used Angular 9 with .net core 3.1
Thank you so much for this content :)
Hi Please help me on this error, I am not getting where I am doing a mistake.
ERROR in src/app/payment-details/payment-detail/payment-detail.component.ts:34:36 – error TS2554: Expected 0 arguments, but got 1.
34 this.service.postPaymentDetail(form.value).subscribe(
Great Tutorial, but i get an error console net::ERR_EMPTY_RESPONSE.
But if a try with Postman Works!
Submit button doesnt work at all.
by the way what’s the right way to run the application? CTRL+F5 ? or “ng serve –open” in power shell??
thank you for your helpful post…
Change the (submit) to (click) in your html and it will work. there are a few typo’s in this tutorial.
Great tutorial, but i get an error message “Cannot Get” on localhost:4200.
Whats wrong ? i Startet the API as EXE after Distribution, and the App on Port 4200
It wasn’t working for me so I had to make service public in payment-detail component. Then all was fine.
Thanks for this Tutorial. Could you suggest changes for .Net Core 3.1 ? I am having issues with it for POST api call.
I got an error message “400 bad request” when insert value.
looks like something went wrong in your asp.net core API. try to run the API in debug mode with a breakpoint.
It work now. Thanks! Great article!
Short and Sweet. It helps a lot. Thanks
Great article
hi , thanks for the tutorial, I followed your video step by step but in validation of inputs I faced some problems. I inspect my input text but the ng classes of ng-valid, ng-invalid and ng-touched doesn’t exist!
I copied all input element here:
as you can see there is just “form-control” in my app.
and also I realized that my form has a class “novalidate”, I didn’t create this field in my code.
I use Angular CLI: 9.1.3
Node: 12.16.2
OS: win32 x64
typescript 3.8.3
I wonder if you help me on this issue
Hi
I am getting the following error
ERROR in src/app/payment-details/payment-detail/payment-detail.component.html:2:47 – error TS2339: Property ‘service’ does not exist on type ‘PaymentDetailComponent’.
I am new to this so dont now what this means
any help will be appreciated
did you inject the service class in paymentDetail component?
same here
I also got this error.any suggestions to resolve this.?
There is a typo – change pubic to public (missing the L) error should go away.
I am also getting this error and I tried to resolve it but I failed. :(
Use “service.formData.CardOwnerName” instead of “service.CardOwnerName” on the [(ngModel)] in payment-detail.component.html.It’s work
It is very nice content , which is also more useful.
i am requesting to perform one more crud operations on Ag-Grid in angular -9 , as there is no such content in web.
Also puling users from active directory , if gives us with good examples it will be very much useful , as there are no such examples on web.
Thanks
Good article. Might I suggest introducing string interpolation though as it seems to be the status quo. For instance:
putPaymentDetail() {
return this.http.put(this.rootURL + ‘/PaymentDetail/’+ this.formData.PMId, this.formData);
}
Could be
putPaymentDetail() {
return this.http.put(`this.rootURL/${PaymentDetail}/${this.formData.PMId}`, this.formData);
}
thanks for the info.
Hello
Do not be tired
The best training I saw. Thank you