Configure error logging using Serilog.Sinks.Postgres and appSettings.json

Install nuget packages
Serilog.Sinks.PostgreSQL
Microsoft.Extensions.Configuration.Json

Program.cs:

public class Program
   {
     public static void Main(string[] args)
     {
       var path = Directory.GetCurrentDirectory();
       var environmentName =Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production";
      var configuration = new ConfigurationBuilder()
         .SetBasePath(path)
         .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
         .AddJsonFile($"appsettings.{environmentName}.json", optional: true, reloadOnChange: true)
         .AddEnvironmentVariables()
         .Build();
       Log.Logger = new LoggerConfiguration().
         Enrich.FromLogContext().
         ReadFrom.Configuration(configuration).
         CreateLogger();
      try
       {
         var iWebHost = CreateWebHostBuilder(args).Build();
         Log.Information("Application starting");
         iWebHost.Run();
       }
       catch (Exception exception)
       {
         Log.Error(exception.ToString());
       }
       finally
       {
         Log.CloseAndFlush();
       }
     }
    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
        .UseStartup()
        .UseSerilog();
   }

appsettings.json:

"Serilog": {
     "Using": [ "Serilog.Sinks.PostgreSQL" ],
     "MinimumLevel": "Warning",
     "WriteTo": [
       {
         "Name": "PostgreSQL",
         "Args": {
           "connectionString": "",
           "tableName": "Logs",
           "needAutoCreateTable": true,
           "batchPostingLimit": 1
         }
       }
     ]
   }
Continue Reading

Fix for ‘’Npgsql.PostgresException: syntax error at or near ‘[‘”

We decided to change our database from SQL server to Postgres in our application. When I tried to apply the database migrations to the database it failed with a
Npgsql.PostgresException (0x80004005): 42601: syntax error at or near "[" error.
On further analyzing the issue I found that this issue occurs as the migrations were created on SQL Server and contain SQL Server-specific code.

To fix this issue, I
a. Removed the Migrations folder in your application.
b. Ran “Add-Migration Init” in the package manager console
c. Ran “Update-Database”, to flush the SQL Server predefined context.

Continue Reading

“Error starting userland proxy: Bind for unexpected error Permission denied” error when debugging ASP.Net Core application

If you get an “Error starting userland proxy: Bind for unexpected error Permission denied” error, when debugging your ASP.Net Core application in Docker, then run the following command to find the excluded ports range, being used by different applications:

netsh int ip show excludedportrange protocol=tcp

image

I then change my launchSettings.json file to use a port that is not reserved

{
  "iisSettings": {
    "windowsAuthentication": false,
    "anonymousAuthentication": true,
    "iisExpress": {
      "applicationUrl": "//localhost:50504",
      "sslPort": 44392
    }
  },
  "profiles": {
    "IIS Express": {
      "commandName": "IISExpress",
      "launchBrowser": true,
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    },
    "Scrubber": {
      "commandName": "Project",
      "launchBrowser": true,
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      },
      "applicationUrl": "//localhost:5001;//localhost:5000"
    },
    "Docker": {
      "commandName": "Docker",
      "launchBrowser": true,
      "launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}",
      "environmentVariables": {
        "ASPNETCORE_URLS": "//+:443;//+:80",
        "ASPNETCORE_HTTPS_PORT": "44393"
      },
       "httpPort": 54558,
      "useSSL": true,
      "sslPort": 44393
    }
  }
}
Continue Reading

Deploy a ASP.Net Core application to Digital Ocean

  • Make sure that your source code is checked into Github. Check in the DockerFile in the root of the repository.
  • Create a account in DockerHub at //hub.docker.com/.
    Create a new repository and connect your github repository. 
    Click Create & Build. With this, when new changes are checked into your Github repository it will be automatically build in DockerHub and a new image created.

    image

Create a new account\Login in Digital Ocean.
Create a new Droplet.

image

Select Docker and select the 5$\month plan.  Select One time password for Authentication.
Click create Droplet.

image

After the droplet is created, click the droplet.
image

Then click the console link on the right hand side.
image

In the console window, login into the your droplet using the login id and one time password, provided in email. You will be asked to change the password.
To install the application, in the console window, login into docker hub using the following command:

login docker

pull the image for your application using the following command:

docker pull ajitgoel/socialmediascrubber

To run the docker image, use the following command:

docker run –p 80:80 ajitgoel/socialmediascrubber

your website should now be visible at

//<PublicIpAddress>
Continue Reading

Azure App service for containers error: repository does not exist or may require ‘docker login’

I have configured my ASP.Net Core 2.2 application for continuous build and deploy through Visual Studio 2019. I also see that the image has been build and the deploy successful in Azure DevOps. However in my App service’s application logs, I see the following errors:

2019-07-03 05:44:22.174 ERROR - Pulling docker image productssimplerregistry/simpler.products:5 failed:
2019-07-03 05:44:22.179 INFO  - Pulling image from Docker hub: productssimplerregistry/simpler.products:5
2019-07-03 05:44:23.663 ERROR - DockerApiException: Docker API responded with status code=NotFound, response={"message":"pull access denied for productssimplerregistry/simpler.products, repository does not exist or may require 'docker login'"}
2019-07-03 05:44:26.233 ERROR - Image pull failed: Verify docker image configuration and credentials (if using private repository)

To fix the issue, you should ensure that your application’s pipeline’s Azure Container Registry is the fully qualified name like  productssimplerregistry.containers.azurecr.io instead of just productssimplerregistry.

2019-07-03 19_23_27-Window

Continue Reading

Configuring Serilog SQL server sink logging for ASP.Net Core application

Here are the changes that you need to make in your ASP.Net Core web application to configure Serilog logging with SQL server sink.

a. Install the following libraries from Nuget, using the Nuget Package Manager
Serilog.AspNetCore
Serilog.Extensions.Logging
Serilog.Settings.AppSettings
Serilog.Settings.Configuration
Serilog.Sinks.MSSqlServer

b. Program.cs:


using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Serilog;
using System;
using System.IO;

namespace Scrubber
{
  public class Program
  {
    public static void Main(string[] args)
    {
      var path = Directory.GetCurrentDirectory();
      var environmentName =Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production";

      var configuration = new ConfigurationBuilder()
      .SetBasePath(path)
      .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
      .AddJsonFile($"appsettings.{environmentName}.json", optional: false, reloadOnChange: true)
      .Build();

      Log.Logger = new LoggerConfiguration()
        .Enrich.FromLogContext()
        .ReadFrom.Configuration(configuration)
        .CreateLogger();

      try
      {
        WebHost.CreateDefaultBuilder(args)
          .UseStartup()
          .UseSerilog()
          .Build()
          .Run();
      }
      finally
      {
        Log.CloseAndFlush();
      }
    }
  }
}

AppSettings.json:


{
  "Serilog": {
    "Using": [ "Serilog.Sinks.MSSqlServer" ],
    "MinimumLevel": "Information",
    "WriteTo": [
      {
        "Name": "MSSqlServer",
        "Args": {
          "connectionString": "YourSQLServerConnectionString",
          "tableName": "Logs",
          "autoCreateSqlTable": true
        }
      }
    ]
  }
}
Continue Reading

Configuring Azure app services logging for ASP.Net Core application

If you are using Azure to host your ASP.Net Core website and don’t want to spend time configuring logging in your web application, then you can use Azure App services logging. Here are the changes that you need to make in your web application to configure logging.

Startup.cs:


using Microsoft.Extensions.Logging.AzureAppServices;
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
         services.Configure<AzureFileLoggerOptions>
(Configuration.GetSection("AzureAppServicesLogging"));
} }

AppSettings.json:


{
"AzureAppServicesLogging": {
"BlobName": "Log.txt"
}
}

I have also turned Detailed error messages on, so I can more glean more details if an error occurs.

image

image

Continue Reading

Send emails using SendGrid Email provider and ASP.Net Core

Sending emails using SendGrid email provider and ASP.Net Core is very straightforward.
Firstly install SendGrid package through Package Manager Console using the following command

install-package SendGrid

Now create a account in Sendgrid.com and add an API key to use the SendGrid provider service.  Add this key to your AppSettings.Json or AppSettings.Development.Json under a new SendGridEmailSettings=>SendGridKey node.

image

AppSettings.Json:

{
"SendGridEmailSettings": {
"SendGridKey": <SendGrid Private API Key>
}
}

StartUp.cs:

public void ConfigureServices(IServiceCollection services)
{
……………………..
services.AddTransient<IEmailSender, EmailSender>();
services.Configure<AuthMessageSenderOptions>(options =>
Configuration.GetSection("SendGridEmailSettings").Bind(options));
}

EmailSender .cs

using Microsoft.AspNetCore.Identity.UI.Services;
using Microsoft.Extensions.Options;
using SendGrid;
using SendGrid.Helpers.Mail;
using System.Threading.Tasks;

public class AuthMessageSenderOptions
{
public string SendGridUser { get; set; }
public string SendGridKey { get; set; }
}
public class EmailSender : IEmailSender
{
public EmailSender(IOptions optionsAccessor)
{
Options = optionsAccessor.Value;
}
public AuthMessageSenderOptions Options { get; } //set only via Secret Manager
public Task SendEmailAsync(string email, string subject, string message)
{
return Execute(Options.SendGridKey, subject, message, email);
}
public Task Execute(string apiKey, string subject, string message, string email)
{
var sendGridClient = new SendGridClient(apiKey);
var sendGridMessage = new SendGridMessage()
{
From = new EmailAddress("ajitgoel@gmail.com", "Simpler Products-Social Media Scrubber"),
Subject = subject,
PlainTextContent = message,
HtmlContent = message
};
sendGridMessage.AddTo(new EmailAddress(email));
// Disable click tracking.See //sendgrid.com/docs/User_Guide/Settings/tracking.html
sendGridMessage.SetClickTracking(false, false);
return sendGridClient.SendEmailAsync(sendGridMessage);
}
}

If you send an email and you do not receive it in your mailbox check the spam folder. My emails landed in the spam folder when I was testing the application.

Continue Reading

NotSupportedException: No IUserTwoFactorTokenProvider named ‘Default’ is registered.

If you have changed the AddDefaultIdentity in the Startup.cs file to AddIdentity and you receive a

An unhandled exception occurred while processing the request.
NotSupportedException: No IUserTwoFactorTokenProvider<TUser> named ‘Default’ is registered.
Microsoft.AspNetCore.Identity.UserManager<TUser>.GenerateUserTokenAsync(TUser user, string tokenProvider, string purpose)

error when registering a user, there is a easy fix. You need to a add a AddDefaultTokenProviders() when adding identity() to services.

public void ConfigureServices(IServiceCollection services)
  {
  ………………
  services.AddIdentity<User, UserRole>()
   .AddEntityFrameworkStores<ApplicationDbContext>()
   .AddDefaultTokenProviders();
…………………….

Continue Reading