How to Get Client IP Address in ASP.NET Core

I was working on this ASP.NET Core 3 project for a client, and he asked me to capture the current client IP address. So, I thought it would be beneficial I write a quick post to share with you how I was able to get this done.

I remember when working in classic ASP.NET, in order to get the user IP address we would simply access the request of the current HTTP context or directly accessing the request. However, things changed in ASP.NET Core a little. Therefore, let’s explore how we can get the current user’s IP address in an ASP.NET Core 3 MVC application.

Ways to get IP in Classic ASP.NET

  • Example HttpContext.Current.Request.UserHostAddress

           var ip =  HttpContext.Current.Request.UserHostAddress; 
         
  • Example Request.UserHostAddress

          var ip = Request.UserHostAddress;  
         

Create a New ASP.NET Core Web Project

We are going to create a new ASP.NET Core 3 WEB application and use that as our demonstration. I am using Visual Studio 2019 for this demo.

  • Create a .NET Core 3.x Web application and click next.
  • On the next popup, provide a name for the application. let’s call it “ClientIPAdressDemo”. Then, click create.
  • Select the “Web Application (Model-View-Controller)” template as shown below and click create.
  • Once the project is done created and Visual studio restores the nuget packages, simply run the application. And you should see a “Welcome” displayed in browser as shown below.

Way to get client IP address in ASP.NET Core

Now that we have a working solution, let’s inject the HttpContextAccessor instance in the ConfigureServices method from the Startup.cs class. You maybe have to add this reference using Microsoft.AspNetCore.Http.

 
  public void ConfigureServices(IServiceCollection services)
  {
    services.AddControllersWithViews();
    services.AddSingleton<IActionContextAccessor, ActionContextAccessor>();
  }

Next, we’ll update the HomeController to inject the IActionContextAccessor in the constructor. But first let’s declare a variable.

 private readonly IActionContextAccessor _accessor;

Now, let’s inject the IActionContextAccessor into the controller’s constructor with DI.

  public HomeController(ILogger logger, IActionContextAccessor accessor)
  {
    _logger = logger;
    _accessor = accessor;
  }

Finally, we can retrieve the IP address from the accessor variable.

public IActionResult Index()
{
  var ip = _accessor.ActionContext.HttpContext.Connection.RemoteIpAddress.ToString();
  return View();
}

Just a minor note…
In case you don’t want to use DI, you can always access the IP information directly in the controller as followed.

var ip =HttpContext.Connection.RemoteIpAddress.ToString()

Interesting Features about JSON.stringify

If you’ve been working with JavaScript in the past, you probably used this cool JSON.stringify method to convert some type of JavaScript value into its JSON string representation. Such method can be used with simple data types like strings and numbers. We probably have used this daily, but unaware of the extra feature available to use in JSON.stringify method. Therefore, in this post we’re going to explore some basic features we can use instantly in our next JavaScript code. To follow along, check out this demo link.

The basic

var cities= ['Miami', 'Orlando', 'Los Angeles', 'New York', 'Chicago'];
var json = JSON.stringify(cities); 

console.log(json);
//["Miami","Orlando","Los Angeles","New York","Chicago"]

If you look closely to the comment in the code snippet above, the array is printed out with no spaces and the single quotes are updated to double quotes.

JavaScript Object Conversion

In some cases you might be working with a JavaScript Object and want to convert it into JSON.

const person = {
  firstName: 'Paul',
  lastName: 'Johnson',
  age: 50,
  jobTitle: 'Manager'
}
var json = JSON.stringify(person);

console.log(json);
//{"firstName":"Paul","lastName":"Johnson","age":50,"jobTitle":"Manager"}

Again, as you can see the object is converted into a string and each property inside the object is shown as well as its value.

Working with Unsupported DataTypes

Not all data types supported by JavaScript can be converted in JSON. Types such as Strings, numbers, booleans, null, arrays, and objects are supported. However, date objects, regular expressions, undefined, and functions are not. How JSON.stringify deals with unsupported data types may differ if they are contained in an object or an array.
In case you have a complex object that can’t be serialized, it will be converted into an empty object or omitted. So beware of that when working with JSON.stringify. Here’s a quick snippet below showing a function and a complex credit object. Let’s see how that goes.

const book = {
  title: 'JSON Stringify Example',
  description: 'Providing great example on how to use JSON stringify',
  year: '2020',
  isOverdue: function() {
    // code here
  },
  credits: new Map([
    ['Jacque Roma'],
    ['Darline Raroule']
  ])
}
var json = JSON.stringify(book);

//{"title":"JSON Stringify Example","description":"Providing great example on how to use JSON stringify","year":"2020","credits":{}}

As you can see above in the output comment the credit object is indeed empty and isOverdue is removed.

Working with the replacer parameter in JSON.stringify

According to this Mozilla postthe replacer parameter can be either a function or an array. This function receives the actual key and value on which the JSON.stringify method is operating on. You are able to change the representation of the value with the function’s return value.
Let’s look at a quick example below on how to use the replacer as a function.

function replacer(key, value) {
  if (value < 1000) {
    return undefined;
  }
  return value;
}

var reviews = {
  books: 5000,
  cars: 3000,
  house: 999,
  boat: 2000
};
json = JSON.stringify(reviews, replacer);
console.log(json);
//{"books":5000,"cars":3000,"boat":2000}

After running the script above, because of the replacer function house is now printed out in the output. This is one way to remove unwanted values from the result.

However, when replacer is an array, the array's values will dictate what returned in the resulting JSON string. Here's a quick example below.

var reviews = {
  books: 5000,
  cars: 3000,
  house: 999,
  boat: 2000
};
json = JSON.stringify(reviews, ['books', 'house','boat'] );
console.log(json);
//{"books":5000,"house":999,"boat":2000}

Use of the space argument

JSON stringify has a third argument which you can use to control the spacing in the final string.

  • Use a number as the third argument ==> will cause each level in the stringification to be indented with this number of space characters up to 10.
    var reviews = {
      books: 5000,
      cars: 3000,
      house: 999,
      boat: 2000
    };
    json = JSON.stringify(reviews, ['books', 'house','boat'], 2);
    console.log(json);
    
    //example result below
    //{
    //  "books": 5000,
    //  "house": 999,
    //  "boat": 2000
    //}
    
  • Use a string as the third argument ==> will cause each level to be indented by this string (or the first ten characters of it). We'll use the same example above.
    var reviews = {
      books: 5000,
      cars: 3000,
      house: 999,
      boat: 2000
    };
    json = JSON.stringify(reviews, ['books', 'house','boat'], 'xx');
    console.log(json);
    
    //example result below
    //{
    //xx"books": 5000,
    //xx"house": 999,
    //xx"boat": 2000
    //}
    

To conclude, I would advise that you try it out for yourself and if this new to look more into the documentation.

Use SQLite in .NET Core 3 With Entity Framework Core

As you might know, ASP.NET is able to support many different types of Database providers. Today, I decided to test the use of SQLite in ASP.NET Core 3 with Entity Framework Core. For a quick demonstration, I’ll create a simple console application. You can follow along.

Create Sample Console Project

Create a .NET Core 3.x console application in Visual Studio 2019.

Next Dialog, give the project a name.

Install Entity Framework Core

When working with EF Core, you will want to install the correct package for the Entity Framework Core database provider you want to target in your project. Since this demo project is regarding SQLite, I am going to install the EF Core that supports SQLite.

Add NuGet package reference

Install-Package Microsoft.EntityFrameworkCore.Sqlite

Now that we have SQLite Support added, let’s add a simple model to the project to use a test.
Right-Click the project name, Add, and Class to add the new model as shown below.


Replace content of the employee model class with the following snippet.

namespace SQLiteAspNetCoreDemo
{
    public class Employee
    {
        public int Id { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public int Age { get; set; }
    }
}

Create DBContext

Now we need to create the DBContext. Add a new class file and name it SQLiteDBContext.cs and add following code.

using Microsoft.EntityFrameworkCore;

namespace SQLiteAspNetCoreDemo
{
    public class SQLiteDBContext : DbContext
    {
        public DbSet Employees { get; set; }
        protected override void OnConfiguring(DbContextOptionsBuilder options)
            => options.UseSqlite("Data Source=sqlitedemo.db");
    }
}

The code above contains a basic DbSet which is used to create the Employees table.
OnConfiguring() method is used for configuring the DBContext. Here the option is set to use Sqlite database and also setting a connection string or data source to connect.

Now, we’re ready to test things out. Let’s try to add some employee data. Open Program.cs and add the following code.

The moment of truth. Before we can try to run the project we’ll need to run migration first using the following commands in Package Manager Console.
First we’ll need to add Microsoft.EntityFrameworkCore.Tools to allow us to create and apply migration.

Install-Package Microsoft.EntityFrameworkCore.Tools

Next, we need to add migration. Since this is the first migration we’re running we’ll call it InitialCreate.

Add-Migration InitialCreate

A new file will be created in the project with the following content

using Microsoft.EntityFrameworkCore.Migrations;

namespace SQLiteAspNetCoreDemo.Migrations
{
    public partial class InitialCreate : Migration
    {
        protected override void Up(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.CreateTable(
                name: "Employees",
                columns: table => new
                {
                    Id = table.Column(nullable: false)
                        .Annotation("Sqlite:Autoincrement", true),
                    FirstName = table.Column(nullable: true),
                    LastName = table.Column(nullable: true),
                    Age = table.Column(nullable: false)
                },
                constraints: table =>
                {
                    table.PrimaryKey("PK_Employees", x => x.Id);
                });
        }

        protected override void Down(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.DropTable(
                name: "Employees");
        }
    }
}

Update-Database

After running the update command above, we can see the result in the output windows as shown below.

Update the program

We can start testing things out and see if it works. Find the Program.cs file and replace its content with the following.
In the code below, we are creating a new employee object and save it in the database.
Next, we read and get the first employee from the database. Of course, it’s a new database therefore, we’re expecting just one entry in the database. Then, we’re updating the employee first name and the age. Last, we’re deleting that employee.

using System;
using System.Linq;

namespace SQLiteAspNetCoreDemo
{
    public class Program
    {
        static void Main(string[] args)
        {
            using (var db = new SQLiteDBContext())
            {
                // Create
                Console.WriteLine("Add New Employee: ");
                db.Employees.Add(new Employee { FirstName = "John", LastName = "Doe", Age = 55 });
                db.SaveChanges();

                Console.WriteLine("Employee has been added sucessfully.");

                // Read
                Console.WriteLine("Querying table for that employee.");
                var employee = db.Employees
                    .OrderBy(b => b.Id)
                    .First();

                Console.WriteLine("The employee found: {0} {1} and is {2} years old.", employee.FirstName, employee.LastName, employee.Age);

                // Update
                Console.WriteLine("Updating the employee first name and age.");

                employee.FirstName = "Louis";
                employee.Age = 90;

                Console.WriteLine("Newly updated employee is: {0} {1} and is {2} years old.", employee.FirstName, employee.LastName, employee.Age);

                db.SaveChanges();

                // Delete
                Console.WriteLine("Delete the employee.");

                db.Remove(employee);
                db.SaveChanges();
            }
        }
    }
}

Test SQLite in ASP.NET Core 3

Finally, the project was run successfully. Below is the output. In case you run into issue with the SQLite table not found, check this post which might help.

SQLite Error 1: ‘no such table: Employees’

I was working on this simple console application with SQLite and got this error below.

DbContext

using Microsoft.EntityFrameworkCore;
using System.IO;

namespace SQLiteAspNetCoreDemo
{
    public class SQLiteDBContext : DbContext
    {
        public DbSet Employees { get; set; }
        protected override void OnConfiguring(DbContextOptionsBuilder options)
            => options.UseSqlite("Data Source=sqlitedemo.db");
    }
}

Error

Unhandled exception. Microsoft.EntityFrameworkCore.DbUpdateException: An error occurred while updating the entries. See the inner exception for details.
—> Microsoft.Data.Sqlite.SqliteException (0x80004005): SQLite Error 1: ‘no such table: Employees’.
at Microsoft.Data.Sqlite.SqliteException.ThrowExceptionForRC(Int32 rc, sqlite3 db)
at Microsoft.Data.Sqlite.SqliteCommand.PrepareAndEnumerateStatements(Stopwatch timer)+MoveNext()
at Microsoft.Data.Sqlite.SqliteCommand.GetStatements(Stopwatch timer)+MoveNext()
at Microsoft.Data.Sqlite.SqliteDataReader.NextResult()
at Microsoft.Data.Sqlite.SqliteCommand.ExecuteReader(CommandBehavior behavior)
at Microsoft.Data.Sqlite.SqliteCommand.ExecuteDbDataReader(CommandBehavior behavior)
at System.Data.Common.DbCommand.ExecuteReader()
at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReader(RelationalCommandParameterObject parameterObject)
at Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.Execute(IRelationalConnection connection)
— End of inner exception stack trace —
at Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.Execute(IRelationalConnection connection)
at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.Execute(DbContext _, ValueTuple`2 parameters)
at Microsoft.EntityFrameworkCore.Storage.Internal.NoopExecutionStrategy.Execute[TState,TResult](TState state, Func`3 operation, Func`3 verifySucceeded)
at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.Execute(IEnumerable`1 commandBatches, IRelationalConnection connection)
at Microsoft.EntityFrameworkCore.Storage.RelationalDatabase.SaveChanges(IList`1 entries)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChanges(IList`1 entriesToSave)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChanges(Boolean acceptAllChangesOnSuccess)
at Microsoft.EntityFrameworkCore.DbContext.SaveChanges(Boolean acceptAllChangesOnSuccess)
at Microsoft.EntityFrameworkCore.DbContext.SaveChanges()

Solution

If you notice in the Exception StackTrace, it says no such table found. The problem had to do with the database path. After updating it to use the absolute path, everything seems to work as expected.

using Microsoft.EntityFrameworkCore;

namespace SQLiteAspNetCoreDemo
{
    public class SQLiteDBContext : DbContext
    {
        public DbSet Employees { get; set; }
        protected override void OnConfiguring(DbContextOptionsBuilder options)
            => options.UseSqlite(@"Data Source=C:\Users\Beken\source\repos\SQLiteAspNetCoreDemo\SQLiteAspNetCoreDemo\sqlitedemo.db");
    }
}

The type or namespace name ‘Hosting’ does not exist in the namespace ‘Microsoft.AspNetCore.Razor’

Current setting




There was an error running the template C:\Users\JeanB\.nuget\packages\microsoft.visualstudio.web.codegenerators.mvc\2.2.1\Templates\ControllerGenerator\MvcControllerWithContext.cshtml: Template Processing Failed:(4,47): error CS0234: The type or namespace name 'Hosting' does not exist in the namespace 'Microsoft.AspNetCore.Razor' (are you missing an assembly reference?)
(20,41): error CS0234: The type or namespace name 'Hosting' does not exist in the namespace 'Microsoft.AspNetCore.Razor' (are you missing an assembly reference?)
   at Microsoft.VisualStudio.Web.CodeGeneration.ActionInvoker.b__6_0()
   at Microsoft.Extensions.CommandLineUtils.CommandLineApplication.Execute(String[] args)
   at Microsoft.VisualStudio.Web.CodeGeneration.ActionInvoker.Execute(String[] args)
   at Microsoft.VisualStudio.Web.CodeGeneration.CodeGenCommand.Execute(String[] args)

Solution

In order to resolve this issue I had to add the following package to the project.

Install-Package Microsoft.AspNetCore.Razor -Version 2.1.1

Not Able To Use UseInMemoryDatabase method In DbContextOptionsBuilder

While working on this demo project, I got this error below

Problem with UseInMemoryDatabase Method

Severity	Code	Description	Project	File	Line	Suppression State
Error	CS1061	'DbContextOptionsBuilder' does not contain a definition for 'UseInMemoryDatabase' and no accessible extension method 'UseInMemoryDatabase' accepting a first argument of type 'DbContextOptionsBuilder' could be found (are you missing a using directive or an assembly reference?)	WebDemoProject	C:\Users\J\Startup.cs	32	Active

Solution

According to EntityFramework Core, in order to be able to use the InMemory reference, you need to have Microsoft.EntityFrameworkCore.InMemory package installed to have access to UseInMemoryDatabase() extension method with DbContextOptionsBuilder. Once I read that and installed it. Voila everything works like champ.

Install-Package Microsoft.EntityFrameworkCore.InMemory

Delete Duplicate Entries In A Sql Server Table

Couple days ago I wrote a quick post demonstrating how to find duplicate records in a SQL server table. A colleague of mine read the post and asked me to show how to delete the duplicates  from the table. Therefore, I thought it would make sense I put this post together on how to delete duplicate entries in a table.

What does it take to remove duplicates from a table?

  • First, we need to validate the data to see the duplicates we are deleting.
    WITH student_cte AS (
        SELECT 
            First_Name, 
    		Last_Name,
    		Phone, 
            ROW_NUMBER() OVER(
                PARTITION BY 
                    First_Name, 
                    Last_Name, 
                    Phone
                ORDER BY 
                    First_Name, 
                    Last_Name, 
                    Phone
            ) rn
         FROM dbo.Students
    )
    select * from student_cte;
    
  • The picture below shows the records that are duplicates with the row count.
  • Now, in order to delete these record, I am going to show the best way to handle using that same CTE query above with a slight modification. I have deleted any instance with rn > 1.
    WITH student_cte AS (
        SELECT 
            First_Name, 
    		Last_Name,
    		Phone, 
            ROW_NUMBER() OVER(
                PARTITION BY 
                    First_Name, 
                    Last_Name, 
                    Phone
                ORDER BY 
                    First_Name, 
                    Last_Name, 
                    Phone
            ) rn
         FROM dbo.Students
    )
    DELETE FROM student_cte WHERE rn >1;
    
  • After running the query above, the duplicated records are now gone.

In this post, I showed how you can get rid of duplicate rows from a table in SQL Server. I hope after reading this article you will be able to use these tips. If you have questions or feedback, please share it with me. I’d like to know what you’re thinking. Please post your feedback, question, or comments about this article.

How To Get Sendgrid API Key To Send E-mails

In Sendgrid there are 3 different types of API keys that you can generate to use in your application. Which one to use depends on your requirements need. Therefore, in this post I am going to show how to setup a simple restricted API key to be used on my next e-mail demo.

Types of API KEYS Available

  • Full Access which allows the API key to access GET, PATCH, PUT, DELETE and POST endpoints for all parts of your account, excluding billing and Email Address Validation.
  • Restricted Access, this is a customized type where you can set levels of access for all parts of your account, excluding billing and Email Address Validation.
  • Billing Access which allows the API key to access billing endpoints for the account.

Steps to create new Sendgrid API Key

  • First, you need to head over to Sendgrid.com and create an account. Once you log into the application, it will take you to the dashboard area. Click on Setting on the left pane to expand it.
  • Next, click on the “API KEY” as shown below. That will open the page to allow you to create a new API KEY.
  • Now, click on the “Create API Key” button at the top right corner, it will open the 3 types of API Key to select and the different options you need to setup.
  • For the purpose of this tutorial, I am going to set this key for sending email only.
  • Once you’re done you will get a key. The API KEY generated and displayed to you just once. So be sure to copy and save it somewhere. After that only the subset key is displayed.

Last, some notes to keep in mind.

Sendgrid only allows 100 keys per account.

Once you delete a key, it can no longer be used to access SendGrid’s services.

 

How to create a simple Todo list Using Jquery

Yes, you heard it, a simple doto list using Jquery. We all know the famous hello world applications when we’re first learning a language. Now, it’s the todo app. In this post I am going to create a simple web todo application using HTML5, CSS3 and Javascript(jQuery).
You can develop this todo application in any text editor and debug in any browser. I’m using Plunker to code this due to its simplicity. You can follow along with using this Plunker demo link

Todo list Using Jquery – Project Setup

First things first, we need to set up our project. Let’s add a new index.html file to our plunker project as shown below.

  
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title></title>
    <link data-require="bootstrap@3.3.6" data-semver="4.1.3" rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" />
    <script data-require="bootstrap@3.3.6" data-semver="4.1.3" src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js"></script>
    <link rel="stylesheet" href="style.css" />
    <script data-require="jquery" data-semver="3.2.1" src="https://cdn.jsdelivr.net/npm/jquery@3.2.1/dist/jquery.min.js"></script>
    <script src="script.js"></script>
  </head>

  <body>
    <div class="col-md-12">
      <h1>Simple Todo Demo!</h1>
      <p>Click on row to delete newly added entry.</p>
      <div data-role="content">
        <ul class="list-group" id="taskListSection">
          <li class="list-group-item active">Todos</li>
          <li class="list-group-item ">1. Example of Existing task</li>
          <li class="list-group-item ">2. Example of Existing task</li>
        </ul>
        <br />
        <fieldset class="ui-grid-a">
          <div class="ui-block-a">
            <textarea placeholder="Enter task" id="taskInputText" cols="50" maxlength="128"></textarea>
          </div>
          <div class="ui-block-b">
            <input type="button" class="btn btn-success" value="Submit" id="taskBtn" />
          </div>
        </fieldset>
      </div>
    </div>
  </body>

</html>
  

Nothing too fancy in that html code. We have a heading and paragraph to let user know to click newly created task. Next is an unordered list group from bootstrap 4 showing 2 items to start with. Think of those two items as existing data from a database. Next is a simple textarea to allow user to type new task entry to add to the list. Last, we have a button which will fire the add operation when user click on it.

Add script to handle add and delete tasks


// Add your javascript here
$(function(){
  $("h1").animate({
    "margin-left": "100px"
  }, "slow");
  

$('#taskBtn').click(function() {
  
    var newTask = $('#taskInputText').val();

    if(newTask !== '') {
      
        var count = $("#taskListSection").children().length;
        
        $('#taskListSection').append('<li class="list-group-item deletetask bg-success">' + count + '. '+ newTask + '</li>');
       
        $('#taskInputText').val('');
        
        deleteTasks();
        
        setTimeout(function(){
          $('#taskListSection li.bg-success').removeClass('bg-success');
        },1000); 
      
    } else {
        alert('Come on, you\'re better than that');   
    }
});  
});

function deleteTasks(){
 $('.deletetask').click(function(){
    $(this).remove();
}); 

}

Again, a simple javascript file containing animation for the heading of the page upon loading. Then, I have a click event listener for when user wants to add a new task to the list. A one second delay is added after the new entry is added to the list and row is highlighted. Then, it is unhighlited after the one second is expired.
A delete function is in there as well to remove the item from the list. Very basic.

Find Duplicate Entries In A Sql Server Table Using CTE

In my last post, I showed how to find duplicate entries in a sql server table using group by which was pretty simple to pull off. I thought it would be a good idea to find the list of all the duplicate rows using CTE for those that are fan of it. We will be using the same table from our previous post on finding duplicate rows which you can read and follow.

What is CTE

A CTE which is short for Common Table Expression, is a temporary result set that you can reference within another query statement. They are used to simplify large queries.

Find duplicate rows CTE

   WITH student_cte AS(
        SELECT  First_Name, 
                Last_Name,
                Phone,  
                COUNT(*) Occurrences
        FROM dbo.students
        GROUP BY
                First_Name, 
                Last_Name,
	        Phone
       HAVING COUNT(*) > 1
  )
  SELECT	st.Id,
		st.First_Name, 
		st.Last_Name,
		st.Phone  		
 FROM dbo.students st
 INNER JOIN student_cte 
  ON student_cte.First_Name = st.First_Name
  AND student_cte.Last_Name = st.Last_Name;

Find duplicate entries result

Find duplicate entries using cte as query