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.

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.

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 Use In-Memory Cache In An ASP.NET Core Web API

Before we can dive into the In-Memory Cache implementation, first, What is caching and when you should consider using it?

Well, caching is basically a technique of storing frequently used data in a temporary storage. Caching can significantly improve the performance and scalability of any application by reducing the time and resources required to load fresh contents. Using that technique will definitely make the end user much happier to use the app.

Types of Caching supported by ASP.Net Core

As you might already know ASP.NET Core supports different types of caching such as In-Memory Cache, Distributed Cache and Response Cache. However, in this post I will take the opportunity to introduce you to how to use In-Memory Cache in an ASP.Net Core Web API app.

How data is stored

When using the In-Memory Cache feature, the data is stored in the memory of Web Server where a web application is being hosted at. It’s good to remember that an application can be hosted on single Server or multiple Servers in a Server Farm. For those of you that have a single server, you should be just fine using In-Memory Cache with no issues because it doesn’t require much to get running, however, if those running on multiple servers on a server farm MUST ensure that the sessions are sticky.

Setting cache expiration time

When adding an item to the cache you set an expiration, this can be an absolute time, a sliding window or the combination of both. Choosing which one to use depends on your scenario.

Example of how to implement In-Memory Cache

To keep thing simple and easy to follow I am going to implement a quick sample API to retrieve the states name using state abbreviation as code. In order to get start simple create a new blank WEB API project in Visual Studio and follow the steps below to fill in the required pieces or you can download the full sample code from github here.

Injecting the dependency from the startup.cs.

    public void ConfigureServices(IServiceCollection services)
    {
      services.AddMemoryCache();
      services.AddMvc();
    }

Now that the In-Memory Cache service has been added, I can access the cache from inside the controllers by simply injecting an IMemoryCache parameter in the constructors.

    private readonly IMemoryCache _cache;

    public StatesController(IMemoryCache memoryCache)
    {
      _cache = memoryCache;
    }

Get Method setup

Next, I need to set my cache inside the get action method which is used to get the name of the state that matches the search criteria.

   [HttpGet("{stateCode}")]
   public async Task Get(string stateCode)
   {
      string state = string.Empty;
      if (!_cache.TryGetValue("CashedStatesList", out Dictionary states))
      {
       Console.WriteLine("Loading from database or json file into cache");

        states =
           JsonConvert.DeserializeObject>(
           await System.IO.File.ReadAllTextAsync("StatesList.json"));

        MemoryCacheEntryOptions options = new MemoryCacheEntryOptions
        {
         AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(300), // cache will expire in 300 seconds or 5 minutes
         SlidingExpiration = TimeSpan.FromSeconds(60) // cache will expire if inactive for 60 seconds
        };

        if (states != null)
        _cache.Set("CashedStatesList", states, options);
      }
      else
      {
         Console.WriteLine("***Data Found in Cache...***");
      }

      if (states != null)
      {
         state = states.GetValueOrDefault(stateCode);

         if (string.IsNullOrEmpty(state))
         {
           state = "Not found, please try again.";
         }

      }

      if (string.IsNullOrEmpty(state))
      {
         return NoContent();
      }
      return Ok(state);
  }

Reading from data source

In the code snippet above as you can see the very first if condition is checking against the cache dictionary object to load the states list if exist, otherwise, it will continue and load the states from the json file. To be clear here’s the snippet of code that reads the json file and load the states list.

  states =
           JsonConvert.DeserializeObject>(
           await System.IO.File.ReadAllTextAsync("StatesList.json"));

Set cache expiration

Then, once the data was cached, I set some times to when it will expire which is 5 minutes and if no activity they will expire in 60 seconds. You can set these values according to your requirements.

   MemoryCacheEntryOptions options = new MemoryCacheEntryOptions
   {
     AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(300), // cache will expire in 300 seconds or 5 minutes
     SlidingExpiration = TimeSpan.FromSeconds(60) // cache will expire if inactive for 60 seconds
   };

Then, if you continue reading the code above you will notice where the cache is being set as expected.
Last, as you can see from this simple example, the In-Memory cache is can be very beneficial when hosting an application on a single Server. It stores data on Server and improves application performance. Don’t forget to test your app to not depend solely on cached data.
In case you would like to read more about In-Memory cache, please visit these links below.
Cache in-memory in ASP.NET Core

Quick and Easy Way To Set Authorization Header of HttpClient

Earlier today I was working on this application which requires me to make a few calls to a REST API to get some products back in XML format. In order to accomplish this task, I have instantiated an HttpClient object which to make the call. However, I was getting this security error below saying “Required OAuth credentials not provided”.

 

  900902
  Missing Credentials
  Required OAuth credentials not provided

Solution

Of course the error message is self explanatory, I was missing the authorization token in the header.

string url = "https://api.web.com/search/1.0" + ";
using (var client = new HttpClient())
{
  client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/xml"));
  client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "my_authorization_token"); ;
  HttpResponseMessage response = client.GetAsync(new System.Uri(url)).Result;
  string responseBody = response.Content.ReadAsStringAsync().Result;
}