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()

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.

How To Add Swagger To Your Web API In ASP.Net Core 3

What is Swagger?
According to Swagger.io, it is basically an open-source software framework with a large ecosystem of tooling that helps developers design, build, document, and consume RESTful web services. For more reading on Swagger check out there Tools Documentation.

Let’s build a WEB API for this demo

In order for me to be able to show how to add swagger, I will need to implement a simple WEB API in ASP.NET Core. If you would like to follow along, here’s a link to the demo project on GitHub

In this post, you learn how to:

  • Create a web API project.
  • Add a model class and a database context.
  • Scaffold a controller with CRUD methods.
  • Add Swagger

Prerequisites

Create Web API Project

From the File menu, select New > Project.
Select the ASP.NET Core Web Application template and click Next.

Give the project a name or if you would like to follow along, name the project WebApiSwaggerMoviesDemo and click Create.

In the Create a new ASP.NET Core Web Application dialog, confirm that .NET Core and ASP.NET Core 3.0 are selected. Select the API template and click Create.

By default a new API called “WeatherForecast” is created for you.

Test the WeatherForecast API

Before I add to this project, I wanted to test it first to make sure everything is good to go. As, you can see I get a list of temperatures below in JSON format.

Add New Movie API

Now that I know the application is working as expected. I need to add a new Model folder to house the movie model.

In Solution Explorer, right-click the project. Select Add > New Folder. Name the folder Models.

Right-click the Models folder and select Add > Class. Name the class Movie and select Add. Therefore, a new file called Movie.cs is added in the Models folder.

Replace the template code with the following code:

using System;

namespace WebApiSwaggerMoviesDemo.Models
{
    public class Movie
    {
        public string Name { get; set; }
        public string Description { get; set; }
        public string Classification { get; set; }
        public DateTime? ReleaseDate { get; set; }
    }
}

Configure the DB Context

Right-click the Models folder and select Add > Class. Name the class MovieContext and click Add. Then, make sure to replace the content of the file with the following piece of code.

using Microsoft.EntityFrameworkCore;

namespace WebApiSwaggerMoviesDemo.Models
{
    public class MovieContext: DbContext
    {
        public MovieContext(DbContextOptions options)
             : base(options)
        {
        
        }
        public DbSet Movies { get; set; }
    }
}

While developing this demo, I did not have Microsoft.EntityFrameworkCore installed, so I had to get it install via NuGet Package Manager.

Register the DBContext

As you already know ASP.NET Core is designed from the start to support Dependency Injection, therefore I need to register the Database context with the IOC container. Something to note here is that I am also specifying to use In-memory database. The name is also specified.

Replace startup.cs file with the following code below.

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using WebApiSwaggerMoviesDemo.Models;
using Microsoft.EntityFrameworkCore;

namespace WebApiSwaggerMoviesDemo
{
    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.AddDbContext(opt => { opt.UseInMemoryDatabase("MovieList"); });
services.AddControllers(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseHttpsRedirection(); app.UseRouting(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); } } }

Add Movies Controller

In order to add the movie controller, I used the scaffold feature as followed.
Right-click the Controllers folder.

Select Add > New Scaffolded Item.

Select API Controller with actions, using Entity Framework, and then select Add.

In the Add API Controller with actions, using Entity Framework dialog:

Pick Movie (WebApiSwaggerMoviesDemo.Models) in the Model class.
Next,select MovieContext (WebApiSwaggerMoviesDemo.Models) in the Data context class.
Then, click Add.

Install Swagger

I have everything I need in the Web API. It’s time to install Swagger. So, I will use NuGet Package Manager to add SwashBuckle

Install-Package Swashbuckle.AspNetCore -Version 5.0.0-rc4

Once the package has been installed, navigate to the project folder and then open startup.cs and then add the middleware as you see in the below file.

       public void ConfigureServices(IServiceCollection services)
        {
            services.AddDbContext(opt =>
            {
                opt.UseInMemoryDatabase("MovieList");
            });
            services.AddControllers();
 
services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo { Title = "Swagger Movies Demo", Version = "v1" }); });
}

And last, you’ll need to enable Swagger and Swagger UI by updating the configure method as followed.

       public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseHttpsRedirection();

            app.UseRouting();

            app.UseAuthorization();
            app.UseSwagger();
app.UseSwaggerUI(c => { c.SwaggerEndpoint("/swagger/v1/swagger.json", "Swagger Movies Demo V1"); });
app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); }

Start a new debugging session (F5) and navigate to this url http://localhost:[PORT_NUMBER]/swagger. Then, you should see Swagger UI help pages for your APIs.

All in all, let’s add a few movies to test the API. Expand the post ribbon.

After adding a few movies, let use the GET to pull all the movies.

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

How to Send Asp.net Core Email With Sendgrid API

I remember a few months back I wrote a quick post on how I managed to send email using MailKit in one of the projects I was on. Well, as you know there are many different services out there making thing simple to send e-mails from application. Since, I like to test things out first before actually implementing it in a real application, I decided to give Sendgrid a try. Therefore, in this post I will walk you through the steps I took to send emails using the Sendgrid API. Are you ready? Let’s do it!!! Find demo project on GitHub here.

I need to create a brand new application for this post. I am currently using Visual Studio 2019 for this project but feel free to use any other version you may have.

Project Setup

  • First, create a new ASP.NET Core application with the following name “SendgridEmailInAspNetCore”
    “File” –> “New” –> “Project”
    Create new project in Visual Studio 2019
  • A “New Project” dialog will open where you can configure your project such as giving a name and location.
    Configure new project in Visual Studio 2019
  • Make sure the project build properly.
    Now that we have the project setup we need to add the Sendgrid Package using the NuGet Package manager tool.
    Open NuGet free and open-source package manager
    Search and Find the Sendgrid Library in NuGet

Add services folder

  • Let’s add a new folder to the project and called it “Services”. This folder will contain the interface that will be used to send the e-mail.
  • Next we need to add the interface called “IEmailSender.cs”
        
    
        using System.Collections.Generic;
        using System.Threading.Tasks;
    
         namespace SendgridEmailInAspNetCore.Services
         {
           public interface IEmailSender
           {
              Task SendEmailAsync(List<string> emails, string subject, string message);
           }
         }
    
    
  • Add an Implementation class called “EmailSender.cs.
    
    using Microsoft.Extensions.Options;
    using SendGrid;
    using SendGrid.Helpers.Mail;
    using System;
    using System.Collections.Generic;
    using System.Threading.Tasks;
    
    namespace SendgridEmailInAspNetCore.Services
    {
        public class EmailSender:IEmailSender
        {
            public EmailSender(IOptions<EmailAuthOptions> optionsAccessor)
            {
                Options = optionsAccessor.Value;
            }
    
            public EmailAuthOptions Options { get; } //set only via Secret Manager
    
            public Task SendEmailAsync(List<string> emails, string subject, string message)
            {
              
                return Execute(Environment.GetEnvironmentVariable("SENDEMAILDEMO_ENVIRONMENT_SENDGRID_KEY"), subject, message, emails);
            }
    
            public Task Execute(string apiKey, string subject, string message, List<string> emails)
            {
                var client = new SendGridClient(apiKey);
                var msg = new SendGridMessage()
                {
                    From = new EmailAddress("noreply@domain.com", "Bekenty Jean Baptiste"),
                    Subject = subject,
                    PlainTextContent = message,
                    HtmlContent = message
                };
    
                foreach (var email in emails)
                {
                    msg.AddTo(new EmailAddress(email));
                }
    
                Task response = client.SendEmailAsync(msg);
                return response;
            }
        }
    }
    
    
  • Next, we’ll add a new class in that same services folder called “EmailAuthOptions.cs” This will only contain the email secrets from sendgrid.

    namespace SendgridEmailInAspNetCore.Services
    {
        public class EmailAuthOptions
        {
            public string SendGridUser { get; set; }
            public string SendGridKey { get; set; }
        }
    }
    

Register the services

  • Find the Startup.cs file, and the ConfigureServices method. Then, add the following two lines.

            services.Configure(Configuration);
            services.AddTransient<IEmailSender, EmailSender>();
    

Setup the Environment Variable

  • Right click on the project and go to the properties. Then, click the debug tab and add a new environment variable with the following key “SENDEMAILDEMO_ENVIRONMENT_SENDGRID_KEY”. set the value to what you have gotten from Sendgrid.
    Way to configure sendgrid api key

Build E-mail Interace to capture message from user

  • Let’s add a new model called “EmailModel.cs” with the following properties.
    using System.ComponentModel.DataAnnotations;
    
    namespace SendgridEmailInAspNetCore.Models
    {
        public class EmailModel
        {
            [Required]
            [EmailAddress]
            public string Email { get; set; }
            [Required]
            public string Subject { get; set; }
            [Required]
            public string Message { get; set; }
        }
    }
    
  • Now, let’s add a new view called “SendEmail.cshtml” in the HOME folder with the following content.
    
    @model SendgridEmailInAspNetCore.Models.EmailModel
    
    @{
        ViewData["Title"] = "SendEmail";
        Layout = "~/Views/Shared/_Layout.cshtml";
    }
    
    <h2>Send Email With Sendgrid in Asp.Net Core</h2>
    
    <hr />
    <div class="row">
        <div class="col-md-4">
            <form asp-action="SendEmail">
                <div asp-validation-summary="ModelOnly" class="text-danger"></div>
                <div class="form-group">
                    <label asp-for="Email" class="control-label"></label>
                    <input asp-for="Email" class="form-control" />
                    <span asp-validation-for="Email" class="text-danger"></span>
                </div>
                <div class="form-group">
                    <label asp-for="Subject" class="control-label"></label>
                    <input asp-for="Subject" class="form-control" />
                    <span asp-validation-for="Subject" class="text-danger"></span>
                </div>
                <div class="form-group">
                    <label asp-for="Message" class="control-label"></label>
                    <textarea asp-for="Message" class="form-control" cols="100"></textarea>
                    <span asp-validation-for="Message" class="text-danger"></span>
                </div>
                <div class="form-group">
                    <input type="submit" value="Send" class="btn btn-default" />
                </div>
            </form>
        </div>
    </div>
    
    @section Scripts {
        @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
    }
    
           
  • In order to be able to send the email in the controller we’ll need to inject the email service via the constructor so that we can have access to send the emails.
    start the start of the home controller we need to add the follow code snippet.

            
    private readonly IEmailSender _emailSender;
    
     public HomeController(IEmailSender emailSender)
     {
       _emailSender = emailSender;
     }
    
  • Now, we’re ready to add the email action methods to the controller.
        
    public IActionResult SendEmail()
    {
      return View();
    }
    public async Task SendEmail(EmailModel model)
    {
     if (ModelState.IsValid)
     {
       var emails = new List();
       emails.Add(model.Email);
       await _emailSender.SendEmailAsync(emails, model.Subject, model.Message);
     }
     return View(model);
    }
    

Final Asp.net Core Email With Sendgrid

  • Now that we have everything in place let’s run the application and Test it out.
    Voila, the application loaded with no issues. Let’s navigate to the SendEmail page. Try to send email without entering anything, you should notice the validations.
    Testing the Asp.net Core Email With Sendgrid with empty inputs
  • Now, enter a valid email, subject, and a message, then click the send button.
    Send a valid email with Asp.net Core Email With Sendgrid
  • The moment of truth. Bingo, I got the e-mail in my inbox as shown below.
    Verify that the email was sent
    Verify that the email was received.

Disable A Specific User in ASP.NET Core Identity 2.0

I am writing this post simply to document a used case I had a few days ago. I basically wanted to disable a user instead of deleting the meta data from the system.
Since the project was built with regular ASP.Net Core Identity, It didn’t take too long for me to figure this out.

What’s ASP.Net Core Identity?

It is a simple membership system that add login capability to any asp.net Core applications. ASP.Net Core Identity supports external login providers such as Facebook, Twitter, Microsoft, and Google.
In case you would like to learn more about it, feel free to read this post on identity.

Implementation In ASP.NET Core Identity 2.0

I had to add a new property called “IsActive” as shown in the code snippet below to the “ApplicationUser.cs” class to disable the user in the system.

namespace UserApp.Models
{
 //Add profile data for application users by adding properties to the ApplicationUser class
    public class ApplicationUser : IdentityUser
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public bool IsActive { get; set; }
    }
}

Next, I run migration to add the new column to the AspNetUsers table.

Now that I have the new column added to the table, I need to set the IsActive flag during registration.

Where do you update the IsActive flag by default?
Find the action method called RegisterAsync in the “AccountController.cs” and

 public async Task RegisterAsync(RegisterViewModel model, string returnUrl = null)
 {
   ViewData["ReturnUrl"] = returnUrl;
   if (ModelState.IsValid)
   {
        var user = new ApplicationUser
        {
                    FirstName = model.FirstName,
                    LastName = model.LastName,
                    IsActive = true
         };
         var result = await _userManager.CreateAsync(user, model.Password);
         if (result.Succeeded)
         {
           _logger.LogInformation("User created a new account with password.");

            var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
            var callbackUrl = Url.EmailConfirmationLink(user.Id, code, Request.Scheme);
            await _emailSender.SendEmailConfirmationAsync(model.Email, callbackUrl);
            logger.LogInformation("User created a new account with password.");
            return RedirectToAction(nameof(ConfirmRegistration));
         }
         AddErrors(result);
     }

     // If we got this far, something failed, redisplay form
     return View(model);
 }

Finally, after running the application and register a brand new user I was able to verify the data in the database. In case you need already have some existing users, you’ll simply need to run an update query to set their flag to active. That’s it!!!