Thursday, February 13, 2020

Entity Framework Core with Asp .Net Core MVC 3 Code Snippets

Entity Framework Core is the Microsoft's cross, open source, light weight platform framework for data access in .Net applications.

EF Core is an ORM (Object Relation Mapper) which generates most of the data access code. EF Core can be used with a wide range of databases.

 Here I am using SQL Server as the back end.I am going to create a Contact Management System comprising of two tables Groups and Contacts.

Tables

CREATE TABLE [dbo].[Groups](

    [GroupId] [int] IDENTITY(1,1) NOT NULL PRIMARY KEY,

    [GroupName] [varchar](50) NULL)


CREATE TABLE [dbo].[Contacts](

    [ContactId] [int] IDENTITY(1,1) NOT NULL PRIMARY KEY,

    [ContactName] [varchar](40) NULL,

    [Location] [varchar](40) NULL,

    [Phone] [varchar](40) NULL,

    [GroupId] [int] NULL REFERENCES Groups(GroupId))




 Start a new ASP.NET CoreWeb Application.

Select Web Application (Model-View-Controller)


Set reference to Microsoft.EntityFrameworkCore.SqlServer


  Models 

Model represents object oriented representation of tables.

 Models/Group.cs

using System.Collections.Generic;

using System.ComponentModel.DataAnnotations;

namespace EFCoreMVC.Models

{

    public class Group

    {

        [Key]

        public int GroupId { get; set; }

        public string GroupName { get; set; }

        public List<Contacts> { get; set; }
    }
}


Models/Contact.cs

namespace EFCoreMVC.Models

{

    public class Contact

    {

        public int ContactId { get; set; }

        public string ContactName { get; set; }

        public string Location { get; set; }

        public Group Groups { get; set; }

    }

}


Groups/SimplifiedContactManagementContext
using Microsoft.EntityFrameworkCore;


namespace EFCoreMVC.Models

{

    public class SimplifiedContactManagementContext : DbContext

    {

        public DbSet Groups { get; set; }
        public DbSet Contacts { get; set; }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseSqlServer("Data Source=.;Initial Catalog=SimplifiedContactManagement;Integrated Security=True");
            base.OnConfiguring(optionsBuilder);
        }
    }
}

Startup.cs
public void ConfigureServices(IServiceCollection services)
{
     services.AddControllersWithViews();
     services.AddScoped ();
}
 

Controllers

GroupsController
using EFCoreMVC.Models;

using Microsoft.AspNetCore.Mvc;

using Microsoft.EntityFrameworkCore;

using System.Linq;

using System.Threading.Tasks;


namespace EFCoreMVC.Controllers

{

    public class GroupsController : Controller

    {

        private readonly SimplifiedContactManagementContext _context;


        public GroupsController(SimplifiedContactManagementContext context)

        {

            _context = context;

        }


        // GET: Groups

        public async Task Index()
        {
            return View(await _context.Groups.ToListAsync());
        }

        // GET: Groups/Details/5
        public async Task Details(int? id)
        {
            if (id == null)
            {
                return NotFound();
            }

            var @group = await _context.Groups
                .FirstOrDefaultAsync(m =&gt; m.GroupId == id);
            if (@group == null)
            {
                return NotFound();
            }

            return View(@group);
        }

        // GET: Groups/Create
        public IActionResult Create()
        {
            return View();
        }

        // POST: Groups/Create
        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task Create([Bind("GroupId,GroupName")] Group @group)
        {
            if (ModelState.IsValid)
            {
                _context.Add(@group);
                await _context.SaveChangesAsync();
                return RedirectToAction(nameof(Index));
            }
            return View(@group);
        }

        // GET: Groups/Edit/5
        public async Task Edit(int? id)
        {
            if (id == null)
            {
                return NotFound();
            }

            var @group = await _context.Groups.FindAsync(id);
            if (@group == null)
            {
                return NotFound();
            }
            return View(@group);
        }

        // POST: Groups/Edit/5
        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task Edit(int id, [Bind("GroupId,GroupName")] Group @group)
        {
            if (id != @group.GroupId)
            {
                return NotFound();
            }

            if (ModelState.IsValid)
            {
                try
                {
                    _context.Update(@group);
                    await _context.SaveChangesAsync();
                }
                catch (DbUpdateConcurrencyException)
                {
                    if (!GroupExists(@group.GroupId))
                    {
                        return NotFound();
                    }
                    else
                    {
                        throw;
                    }
                }
                return RedirectToAction(nameof(Index));
            }
            return View(@group);
        }

        // GET: Groups/Delete/5
        public async Task Delete(int? id)
        {
            if (id == null)
            {
                return NotFound();
            }

            var @group = await _context.Groups
                .FirstOrDefaultAsync(m =&gt; m.GroupId == id);
            if (@group == null)
            {
                return NotFound();
            }

            return View(@group);
        }

        // POST: Groups/Delete/5
        [HttpPost, ActionName("Delete")]
        [ValidateAntiForgeryToken]
        public async Task DeleteConfirmed(int id)
        {
            var @group = await _context.Groups.FindAsync(id);
            _context.Groups.Remove(@group);
            await _context.SaveChangesAsync();
            return RedirectToAction(nameof(Index));
        }

        private bool GroupExists(int id)
        {
            return _context.Groups.Any(e =&gt; e.GroupId == id);
        }
    }
}
 
ContactsController
using EFCoreMVC.Models;

using Microsoft.AspNetCore.Mvc;

using Microsoft.EntityFrameworkCore;

using System.Linq;

using System.Threading.Tasks;


namespace EFCoreMVC.Controllers

{

    public class ContactsController : Controller

    {

        private readonly SimplifiedContactManagementContext _context;


        public ContactsController(SimplifiedContactManagementContext context)

        {

            _context = context;

        }


        // GET: Contacts

        public async Task Index()
        {
           
            return View(await _context.Contacts.ToListAsync());
        }

        // GET: Contacts/Details/5
        public async Task Details(int? id)
        {
            if (id == null)
            {
                return NotFound();
            }

            var contact = await _context.Contacts
                .FirstOrDefaultAsync(m =&gt; m.ContactId == id);
            if (contact == null)
            {
                return NotFound();
            }

            return View(contact);
        }

        // GET: Contacts/Create
        public IActionResult Create()
        {
            return View();
        }

        // POST: Contacts/Create
        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task Create([Bind("ContactId,ContactName,Location")] Contact contact)
        {
            if (ModelState.IsValid)
            {
                _context.Add(contact);
                await _context.SaveChangesAsync();
                return RedirectToAction(nameof(Index));
            }
            return View(contact);
        }

        // GET: Contacts/Edit/5
        public async Task Edit(int? id)
        {
            if (id == null)
            {
                return NotFound();
            }

            var contact = await _context.Contacts.FindAsync(id);
            if (contact == null)
            {
                return NotFound();
            }
            return View(contact);
        }

        // POST: Contacts/Edit/5
        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task Edit(int id, [Bind("ContactId,ContactName,Location")] Contact contact)
        {
            if (id != contact.ContactId)
            {
                return NotFound();
            }

            if (ModelState.IsValid)
            {
                try
                {
                    _context.Update(contact);
                    await _context.SaveChangesAsync();
                }
                catch (DbUpdateConcurrencyException)
                {
                    if (!ContactExists(contact.ContactId))
                    {
                        return NotFound();
                    }
                    else
                    {
                        throw;
                    }
                }
                return RedirectToAction(nameof(Index));
            }
            return View(contact);
        }

        // GET: Contacts/Delete/5
        public async Task Delete(int? id)
        {
            if (id == null)
            {
                return NotFound();
            }

            var contact = await _context.Contacts
                .FirstOrDefaultAsync(m =&gt; m.ContactId == id);
            if (contact == null)
            {
                return NotFound();
            }

            return View(contact);
        }

        // POST: Contacts/Delete/5
        [HttpPost, ActionName("Delete")]
        [ValidateAntiForgeryToken]
        public async Task DeleteConfirmed(int id)
        {
            var contact = await _context.Contacts.FindAsync(id);
            _context.Contacts.Remove(contact);
            await _context.SaveChangesAsync();
            return RedirectToAction(nameof(Index));
        }

        private bool ContactExists(int id)
        {
            return _context.Contacts.Any(e =&gt; e.ContactId == id);
        }
    }
}
 



 
Groups Views
 Index  
@model IEnumerable<EFCoreMVC.Models.Group>

@{
    ViewData["Title"] = "Index";
}

<h1>Index</h1>

<p>
    <a asp-action="Create">Create New</a>
</p>
<table class="table">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.GroupName)
            </th>
            <th></th>
        </tr>
    </thead>
    <tbody>
@foreach (var item in Model) {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.GroupName)
            </td>
            <td>
                <a asp-action="Edit" asp-route-id="@item.GroupId">Edit</a> |
                <a asp-action="Details" asp-route-id="@item.GroupId">Details</a> |
                <a asp-action="Delete" asp-route-id="@item.GroupId">Delete</a>
            </td>
        </tr>
}
    </tbody>
</table>

Details
@model EFCoreMVC.Models.Group

@{
    ViewData["Title"] = "Details";
}

<h1>Details</h1>

<div>
    <h4>Group</h4>
    <hr />
    <dl class="row">
        <dt class = "col-sm-2">
            @Html.DisplayNameFor(model => model.GroupName)
        </dt>
        <dd class = "col-sm-10">
            @Html.DisplayFor(model => model.GroupName)
        </dd>
    </dl>
</div>
<div>
    <a asp-action="Edit" asp-route-id="@Model.GroupId">Edit</a> |
    <a asp-action="Index">Back to List</a>
</div>


Delete
@model EFCoreMVC.Models.Group

@{
    ViewData["Title"] = "Delete";
}

<h1>Delete</h1>

<h3>Are you sure you want to delete this?</h3>
<div>
    <h4>Group</h4>
    <hr />
    <dl class="row">
        <dt class = "col-sm-2">
            @Html.DisplayNameFor(model => model.GroupName)
        </dt>
        <dd class = "col-sm-10">
            @Html.DisplayFor(model => model.GroupName)
        </dd>
    </dl>
    
    <form asp-action="Delete">
        <input type="hidden" asp-for="GroupId" />
        <input type="submit" value="Delete" class="btn btn-danger" /> |
        <a asp-action="Index">Back to List</a>
    </form>
</div>


Edit


@model EFCoreMVC.Models.Group

@{
    ViewData["Title"] = "Edit";
}

<h4>Group</h4>
<hr />
<div class="row">
    <div class="col-md-4">
        <form asp-action="Edit">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
            <input type="hidden" asp-for="GroupId" />
            <div class="form-group">
                <label asp-for="GroupName" class="control-label"></label>
                <input asp-for="GroupName" class="form-control" />
                <span asp-validation-for="GroupName" class="text-danger"></span>
            </div>
            <div class="form-group">
                <input type="submit" value="Save" class="btn btn-primary" />
            </div>
        </form>
    </div>
</div>

<div>
    <a asp-action="Index">Back to List</a>
</div>

@section Scripts {
    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}

Create
@model EFCoreMVC.Models.Group

@{
    ViewData["Title"] = "Create";
}

<h1>Create</h1>

<h4>Group</h4>
<hr />
<div class="row">
    <div class="col-md-4">
        <form asp-action="Create">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
            <div class="form-group">
                <label asp-for="GroupName" class="control-label"></label>
                <input asp-for="GroupName" class="form-control" />
                <span asp-validation-for="GroupName" class="text-danger"></span>
            </div>
            <div class="form-group">
                <input type="submit" value="Create" class="btn btn-primary" />
            </div>
        </form>
    </div>
</div>

<div>
    <a asp-action="Index">Back to List</a>
</div>

@section Scripts {
    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}


Contacts Views

Index

@model IEnumerable<EFCoreMVC.Models.Contact>

@{
    ViewData["Title"] = "Index";
}

<h1>Index</h1>

<p>
    <a asp-action="Create">Create New</a>
</p>
<table class="table">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.ContactName)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Location)
            </th>
            <th></th>
        </tr>
    </thead>
    <tbody>
@foreach (var item in Model) {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.ContactName)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Location)
            </td>
            <td>
                <a asp-action="Edit" asp-route-id="@item.ContactId">Edit</a> |
                <a asp-action="Details" asp-route-id="@item.ContactId">Details</a> |
                <a asp-action="Delete" asp-route-id="@item.ContactId">Delete</a>
            </td>
        </tr>
}
    </tbody>
</table>




Detail
@model EFCoreMVC.Models.Group

@{
    ViewData["Title"] = "Details";
}

<h1>Details</h1>

<div>
    <h4>Group</h4>
    <hr />
    <dl class="row">
        <dt class = "col-sm-2">
            @Html.DisplayNameFor(model => model.GroupName)
        </dt>
        <dd class = "col-sm-10">
            @Html.DisplayFor(model => model.GroupName)
        </dd>
    </dl>
</div>
<div>
    <a asp-action="Edit" asp-route-id="@Model.GroupId">Edit</a> |
    <a asp-action="Index">Back to List</a>
</div>

Delete
@model EFCoreMVC.Models.Group

@{
    ViewData["Title"] = "Delete";
}

<h1>Delete</h1>

<h3>Are you sure you want to delete this?</h3>
<div>
    <h4>Group</h4>
    <hr />
    <dl class="row">
        <dt class = "col-sm-2">
            @Html.DisplayNameFor(model => model.GroupName)
        </dt>
        <dd class = "col-sm-10">
            @Html.DisplayFor(model => model.GroupName)
        </dd>
    </dl>
    
    <form asp-action="Delete">
        <input type="hidden" asp-for="GroupId" />
        <input type="submit" value="Delete" class="btn btn-danger" /> |
        <a asp-action="Index">Back to List</a>
    </form>
</div>


Edit
@model EFCoreMVC.Models.Group

@{
    ViewData["Title"] = "Edit";
}

<h1>Edit</h1>

<h4>Group</h4>
<hr />
<div class="row">
    <div class="col-md-4">
        <form asp-action="Edit">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
            <input type="hidden" asp-for="GroupId" />
            <div class="form-group">
                <label asp-for="GroupName" class="control-label"></label>
                <input asp-for="GroupName" class="form-control" />
                <span asp-validation-for="GroupName" class="text-danger"></span>
            </div>
            <div class="form-group">
                <input type="submit" value="Save" class="btn btn-primary" />
            </div>
        </form>
    </div>
</div>

<div>
    <a asp-action="Index">Back to List</a>
</div>

@section Scripts {
    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}


Create
@model EFCoreMVC.Models.Group

@{
    ViewData["Title"] = "Create";
}

<h1>Create</h1>

<h4>Group</h4>
<hr />
<div class="row">
    <div class="col-md-4">
        <form asp-action="Create">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
            <div class="form-group">
                <label asp-for="GroupName" class="control-label"></label>
                <input asp-for="GroupName" class="form-control" />
                <span asp-validation-for="GroupName" class="text-danger"></span>
            </div>
            <div class="form-group">
                <input type="submit" value="Create" class="btn btn-primary" />
            </div>
        </form>
    </div>
</div>

<div>
    <a asp-action="Index">Back to List</a>
</div>

@section Scripts {
    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}

.Net Core Configuration

appsettings.josn

{
"Name":  "Shalvin",
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
}

index.cshtml

@inject Microsoft.Extensions.Configuration.IConfiguration Configuration
@{
    ViewData["Title"] = "Home Page";
}



<div>
    @Configuration["ComputerName"]
</div>

<div>@Configuration["Name"]</div>

Tuesday, January 28, 2020

C# Fundamentals

C# is a popular multi paradigm programming language. I am going to cover C# along with .Net Core.

While speaking about .Net there are two frameworks available. These is the .Net Framework which works only in Windows.
The other is .Net Core which is a multi platform open source technology.

While speaking about .Net there is a Common Language Runtime (CLR).  It is the platform on which the .Net Application works.

Another component of .Net is the Framework Class Library (FCL) which is a collection of classes.

dotnet
Once the .Net Core is installed you can acces the Command Line Interface (CLI) by typing dotnet in the command prompt.




dotnet --info
I can have more information about .Net Core by typing dotnet --info




dotnet --help
If you want help of .Net Command then type the command dotnet --help

dotnet new
Issuing dotnet new command will list the different Project templates available.



Monday, January 13, 2020

Task and async await in C#

While running an application, the application will spawn a thread.  As this thread execution completes the application exits.

private void HelloButton_Click(object sender, EventArgs e)
{
    Thread.Sleep(4000);
    MessageBox.Show("Hello");
}

In this example I causing the thread to sleep for 4 seconds by calling Thread class's Sleep method. Thread class is found within System.Threading namespace.  It is followed by a MessageBox. The UI will freeze till the MessageBox is shown.

It is possible to spawn additional treads by the main thread thread so that time consuming tasks won't freeze the applicaiton.

Task
Task is a specialized  Thread which implements Thread Pool.


private void HelloButton_Click(object sender, EventArgs e)
{
    Task.Run(() =>
    {
    Thread.Sleep(4000);
    MessageBox.Show("Hello");
    });
}



Let's create an application that fetching content from three web sites and display it in a text box.

In the first example is a Window Forms Application. Using WebClient class which follows the synchronous model. As you click the button the window freezes until the fetching of data is complete. This is because the whole application is running in the main thread.

 private void button1_Click(object sender, EventArgs e)
 {
     var sw = Stopwatch.StartNew();
     string data = string.Empty;
     var address = new List<string>
     {
        "https://www.msn.com/en-in",
        "https://www.irctc.co.in/"
      };
      var client = new WebClient();

      foreach (var item in address)
      {
          data += client.DownloadString(item);
      }

      textBox1.Text = data;
      sw.Stop();
      this.Text = sw.ElapsedMilliseconds.ToString();
    }

In the second example we are using HttpClient class which supports asynchronous class. Also we are using async and await.
private async void button1_Click(object sender, EventArgs e)
        {

            var sw = Stopwatch.StartNew();
            string data = string.Empty;
            var address = new List<string>
            {
                "https://www.msn.com/en-in",
                "https://www.irctc.co.in/"
            };
            var client = new HttpClient();
          
            List<Task<HttpResponseMessage>> responseTasks = new List<Task<HttpResponseMessage>>();
            foreach (var url in address)
            {
                Task<HttpResponseMessage> responseTask = client.GetAsync(url);
                responseTasks.Add(responseTask);
            }
            foreach (var responseTask in responseTasks)
            {
                HttpResponseMessage response = await responseTask;
                data = $"{data} {await response.Content.ReadAsStringAsync()}";
            }
            textBox1.Text = data;
            sw.Stop();
            this.Text = sw.ElapsedMilliseconds.ToString();
        }

Task.Run
private async void button2_Click(object sender, EventArgs e)
        {
            var sw = Stopwatch.StartNew();
            string data = string.Empty;
            var address = new List<string>
            {
                "https://www.msn.com/en-in",
                "https://www.irctc.co.in/"
            };
            var client = new HttpClient();

            List<Task<HttpResponseMessage>> responseTasks = new List<Task<HttpResponseMessage>>();
            foreach (var url in address)
            {
                Task<HttpResponseMessage> responseTask = Task.Run(() => client.GetAsync(url));
                responseTasks.Add(responseTask);
            }
            foreach (var responseTask in responseTasks)
            {
                HttpResponseMessage response = await responseTask;
                data = $"{data} {await response.Content.ReadAsStringAsync()}";
            }
            textBox1.Text = data;
            sw.Stop();
            this.Text = sw.ElapsedMilliseconds.ToString();
        }

Windows Forms DrawEllipse with async Await





  
      private  void Form1_Load(object sender, EventArgs e)
    {
        Task drawTask1 = DrawEllipseAsync(panel1);
        Task drawTask2 = DrawEllipseAsync(panel2);

    }

    private async Task DrawEllipseAsync(Panel panel)
    {
        Random rnd = new Random();

        for (int i = 0; i < 500; i++)
        {
            using (Graphics g = panel.CreateGraphics())
            {
                g.DrawEllipse(
                    Pens.Blue,
                    0,
                    0,
                    rnd.Next(this.Width),
                    rnd.Next(this.Height));
            }

            await Task.Delay(100);
        }
    }
}













MVC
using System.Collections.Generic;
using System.Diagnostics;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web.Mvc;

namespace WebClientMVC.Controllers
{
    public class HomeController : Controller
    {
        

        public ActionResult WebClientEg()
        {
            Stopwatch sw = Stopwatch.StartNew();
            string data = string.Empty;
            List<string> address = new List<string>
            {
                "https://www.msn.com/en-in",
                "https://www.irctc.co.in/"
             };

            using (var client = new WebClient())
            {
                foreach (var item in address)
                {
                    data += client.DownloadString(item);
                }
            }

            sw.Stop();
            ViewBag.Time = sw.ElapsedMilliseconds;
            ViewBag.Data = data;
            return View();
        }

        public async Task<ActionResult> HttpClientAsyncEg()
        {
            Stopwatch sw = Stopwatch.StartNew();
            string data = string.Empty;
            List<string> address = new List<string>
            {
                "https://www.msn.com/en-in",
                "https://www.irctc.co.in/"
             };

            using (var client = new HttpClient())
            {
                foreach (var item in address)
                {
                    var httpResponse = await client.GetAsync(item);
                    data += await httpResponse.Content.ReadAsStringAsync();
                }
            }

            sw.Stop();
            ViewBag.Time = sw.ElapsedMilliseconds;
            ViewBag.Data = data;
            return View();
        }
        public async Task<ActionResult> TaskAsync()
        {
            Stopwatch sw = Stopwatch.StartNew();
            string data = string.Empty;
            List<string> address = new List<string>
            {
                "https://www.msn.com/en-in",
                "https://www.irctc.co.in/"
             };
            List<Task<HttpResponseMessage>> tasks = new List<Task<HttpResponseMessage>>();

            using (var client = new HttpClient())
            {
                foreach (var item in address)
                {
                    tasks.Add(client.GetAsync(item));
                }
                foreach (var task in tasks)
                {
                    var httpResponse = await task;
                    data += await httpResponse.Content.ReadAsStringAsync();
                }
            }

            sw.Stop();
            ViewBag.Time = sw.ElapsedMilliseconds;
            ViewBag.Data = data;
            return View();
        }

Thursday, October 17, 2019

Angular with .Net Core 3 and Visual Studio Code

Visual Studio Code is a cross platform light weight editor. Visual Studio Code can be used to work with a lot of languages and technologies including .Net Core and Angular.

Start a new  .Net Core  Angular Project with Authentication.

dotnet new angular -au Individual -o ngcore


The  above command will create a .Net Core project inside a folder called ngcore.

Navigate to the folder.


code .

Opens the current project folder in Visual Studio Code.

The ClientApp Folder contains the Angular app.

Open the terminal and issue the command


dotnet run 


A few packages are requires for creating Entity Framework Core and Web Api Controller.

 dotnet tool install --global dotnet-ef
dotnet add package Microsoft.VisualStudio.Web.CodeGeneration.Design    

dotnet add package Microsoft.EntityFrameworkCore.SqlServer

dotnet add package Microsoft.EntityFrameworkCore.Tools 

dotnet tool install --global dotnet-aspnet-codegenerator



Proceed on to create Database and Table using sqlcmd tool from terminnal.
sqlcmd -S .
 create database CM
go
use CM
 go
 create table Contacts (ContactId int identity(1,1) primary key, ContactName varchar(40), Location varchar(40))
 go
 insert into Contacts values ('Vishnu', 'Kochi'), ('Sarathlal', 'Kakkanad'), ('Vaishak', 'Palarivattom')
go



For scaffolding the DataContext
dotnet ef dbcontext scaffold  "Data Source=.;Initial Catalog=CM;Integrated Security=True" Microsoft.EntityFrameworkCore.SqlServer -o Models


It will create a DbContext with the Name CMContext (DatabaseName followed by Context suffix) and C# classes corresponding to Database Tables.

Now we want to create WebApis

dotnet-aspnet-codegenerator controller -name ContactsController -api -m ngcore.Models.Contacts -dc CMContext -outDir Controllers 





This command will create a WebApi with the name Contacts using Contact Class previously generated and  Context.

For using the DbContext we can to register it with the Dependency Injection Contrainer. Go to ConfigureServices section in Startup.cs


services.AddScoped<CMContext>();

The controller is ready. We can test the controller with following url https://localhost:5000/api/Contacts.

Angular 
Project created with ng new angular contains  both WebApi and Angular files. The Angular files are placed inside ClientApp folder.

Here I am creating a typescript class called contact.


export class Contact {
  contactId?: number;
  contactName?: string;
  location?: string;
}


HttpClient Get 

Since we have created the Angular project with Individual User Account a lot of code is getting adding. Along with that is the import statement for HttpClient.

Create a contacts componenet with the following command

>ng g c contacts -m appp


import { Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Contact } from '../contact';

@Component({
  selector: 'app-contacts',
  templateUrl: './contacts.component.html',
  styleUrls: ['./contacts.component.css']
})
export class ContactsComponent implements OnInit {

  constructor( private http: HttpClient) { }

  ngOnInit() {
    this.showData();
  }
  contacts: Contact[];

  showData() {
    this.http.get<Contact[]>('https://localhost:44391/api/contacts')
      .subscribe(contacts => this.contacts = contacts);
  }
}

<p>contacts</p>

<ul>
  <li *ngFor="let contact of contacts">
    {{contact.contactName}}
  </li>
</ul>

{{contacts | json}}


HttpClient Post


import { Component, OnInit } from '@angular/core';
import { Contact } from '../contact';
import { HttpClient, HttpHeaders } from '@angular/common/http';

@Component({
  selector: 'app-contact-insert',
  templateUrl: './contact-insert.component.html',
  styleUrls: ['./contact-insert.component.css']
})
export class ContactInsertComponent implements OnInit {

  constructor(private http: HttpClient) { }

  ngOnInit() {
  }

  httpOptions = {
    headers: new HttpHeaders({ 'Content-Type': 'application/json' })
  };

  contact: Contact = {};
  Save() {
    this.http.post<Contact>('https://localhost:44391/api/contacts', this.contact, this.httpOptions)
      .subscribe(
      (data: any) => {
        console.log(data);
        alert('Record Saved')
      });
    
  }
}



<p>Contact Insert</p>

<div>
  <div>
    <label>Name</label>
    <input type="text" name="contactName" [(ngModel)]="contact.contactName" />
  </div>
  <div>
    <label>Location</label>
    <input type="text" name="contactName" [(ngModel)]="contact.location" />
  </div>
  <input type="button" name="name" value="Save" (click)="Save()" />
</div>

{{contact | json}}