How to check/Write logs of Serilog ?

10. May 2020

Question searched on google .

 

How to check whether Serilog internal exception occurs .

 

Serilog not writing logs to database

 

The given ColumnMapping does not match up with any column in the source or destination serilog

 

 

In order to get to know what is making the Serilog not perform its job of logging in to Database server we will enable the Serilogs self logging .
In order to do that we will have to add these lines to Program.cs in Main method.

 

string pathFile = @"Logs/SeriSelf.log";
var file = System.IO.File.CreateText(pathFile);



public static void Main(string[] args)
        {
            var configuration = new ConfigurationBuilder()
                .AddJsonFile("appsettings.json")
                .Build();
            
            string pathFile = @"Logs/SeriSelf.log";
            var file = System.IO.File.CreateText(pathFile);
            
            Serilog.Debugging.SelfLog.Enable(TextWriter.Synchronized(file));
            Log.Logger = new LoggerConfiguration()
                .ReadFrom.Configuration(configuration)
                .WriteTo.Console()
                .CreateLogger();

            try
            {
                Log.Information("Getting the Application Clanstech Running... ");
                CreateHostBuilder(args).Build().Run();

            }
            catch(Exception ex)
            {
                Log.Fatal(ex, "Host terminated unexpectedly");
            }
            finally
            {
                Log.CloseAndFlush();
            }
        }

Now run the application . You will see a log file named SeriSelf.log in Logs Folder . Open it and check if it has any content then there is some problem else Serilog is running fine .


Now for the Question

 

The given ColumnMapping does not match up with any column in the source or destination serilog

 

This happens when the table column does not match with specification of Serilog internal working . In my case i had created the table Log with column LogId as Primary key which was making this error , hence after changing that to Id everything worked fine .

 

ASP.NET MVC Core, Debugging, Exceptions, Logging, Serilog ,

How to write logs to database using Serilog

9. May 2020

Questions searched on google

Serilog writing to Database


Creating Serilog Table from EF Core


XML Type EF Core


Data Annotation XML type


Adding Serilog in .NET Core 3

 

We will use the approach of Entity Framework Core Generated table for Serilog Logging in Database.

First create a Log Entity class in your Models folder with code below code

 

public class Log
    {
        public int Id { get; set; }
        public string Message { get; set; }
        public string MessageTemplate { get; set; }
        public string Level { get; set; }
        public DateTime TimeStamp { get; set; }
        public string Exception { get; set; }
        [Column(TypeName ="Xml")]
        public string Properties { get; set; }
        public string LogEvent { get; set; }
    }

Now goto your context class file and the following code

public virtual DbSet<Log> Logs { get; set; } 

and add the below line in OnModelCreating method

modelBuilder.Entity<Log>().ToTable("Log");

Now we have defined the details of table which we want entity framework to genereate in database. Open the powershell and run the migrations command as below

dotnet ef migrations add Log --context AppContext

Check the migrations file name <timestamp>_Log.cs with the required changes we need and then update the database

dotnet ef database update --context AppContext

Now check the SQL Server Object Explorer with the updated database . A table exists named Log

So we now have the required table for Serilog to begin logging . Now we will configure the serilog for this . Open nuget package manager console and add the below package in order to enable the Serilog sink for MSSqlServer
Serilog.Sinks.MSSqlServer

Add below package in order to activate the serilog configuration reader feature which will read how to connect to MSSqlServer
Serilog.Settings.Configuration

Install-Package Serilog.Sinks.MSSqlServer
Install-Package Serilog.Settings.Configuration

Now we have the basic packages installed , we will add the appsettings for the serilog to connect to the MSSqlServer
Add the below code to your appsettings.json

{
  "Serilog": {
    "Using": [ "Serilog.Sinks.MSSqlServer" ],
    "MinimumLevel": "Information",
    "WriteTo": [
      {
        "Name": "MSSqlServer",
        "Args": {
          "connectionString": "Server=(localdb)\\mssqllocaldb;Database=DatabaseName;Trusted_Connection=True;MultipleActiveResultSets=true", // connection String  
          "tableName": "Log" // table name  
        }
      }
    ]
  }
}

We have kept the table name as "Log" same as we have defined in the AppContext class for entity framework core to create in database server.

Now add the following code in your Program.cs

public class Program
    {
        
        public static void Main(string[] args)
        {
            var configuration = new ConfigurationBuilder()
                .AddJsonFile("appsettings.json")
                .Build();
            Log.Logger = new LoggerConfiguration()
                .ReadFrom.Configuration(configuration)//Serilog.Settings.Configuration
                .WriteTo.Console()
                .CreateLogger();

            try
            {
                Log.Information("Getting the Application Clanstech Application Running... ");
                CreateHostBuilder(args).Build().Run();

            }
            catch(Exception ex)
            {
                Log.Fatal(ex, "Host terminated unexpectedly");
            }
            finally
            {
                Log.CloseAndFlush();
            }
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
            .UseSerilog()//using Serilog.AspNetCore
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
                
            }).UseDefaultServiceProvider(options => options.ValidateScopes = false);
            
    }

Before using .UseSerilog() method do remember to install the package

Install-Package Serilog.AspNetCore

Now run your application and you will see all the logs populated in your Log Table in database server .

References :

https://www.carlrippon.com/asp-net-core-logging-with-serilog-and-sql-server/

https://www.c-sharpcorner.com/article/file-logging-and-ms-sql-logging-using-serilog-with-asp-net-core-2-0/

https://nblumhardt.com/2019/10/serilog-in-aspnetcore-3/

 

ASP.NET MVC Core, C#, Logging, MSSQL, Serilog , , , , ,

Implicit to Explicit implementations of interface in class for Entity Framework Core Common Columns in table like CreatedOn UpdatedOn DeletedOn IsPublished

1. May 2020

Question

I want to make some properties common to entity classes which can be implemented in class. These properties can be selective in nature means some class has one of them or more of them or none. So in order to do that we need multiple inheritance , which can only be implemented by the use of interfaces.

What I searched on internet :

Why entity framework core is not creating columns for the explicit implementations of interface properties

I have created two interfaces with the their properties

 

public interface IRecordInformation
    {
         public DateTime CreatedOn { get; set; }
         public DateTime ModifiedOn { get; set; }

    }
public interface IPublishInformation
    {
        public bool IsPublished { get; set; }
        
    }

Now suppose that I have created the Entity Class as Service and inherited both the interfaces . I have implemented the properties of interfaces which needs to be done . So I got a system where in I can just inherit the interfaces which I need in any class and the common properties will be forced by compiler with an error if I don’t implement them .

 
public class Service : IRecordInformation, IPublishInformation
    {
        public int ServiceId { get; set; }
        public string Name { get; set; }
        public string FileName { get; set; }
        
        public DateTime CreatedOn { get; set; }
        public  DateTime ModifiedOn { get; set; }
        public bool IsPublished { get; set; }
    }

We have achieved avoiding the mistake of forgetting to include CreatedOn ModifiedOn Properties in any class . Now the question is if I want to remove the modifiedOn property from all the class will removing it from interface will work ? answer is no because as soon as I remove the property from interface the compiler thinks that the modifiedOn property is of Service class’s own property which makes our requirement error prone . Hence , what we can do is use explicit implementation of interface properties in class

This can be done like the below example.

public class Service : IRecordInformation, IPublishInformation
    {
        public int ServiceId { get; set; }
        public string Name { get; set; }
        public string FileName { get; set; }
        
        public DateTime IRecordInformation.CreatedOn { get; set; }
        public  DateTime IRecordInformation.ModifiedOn { get; set; }
        public bool IPublishInformation.IsPublished { get; set; }
    }

Now we have achieved that whenever there is any change in interface the compiler will force us to change the class implementation as well . But the problem arises now is the Entity Framework Core does not processes the explicit implementations of interface into table columns . So we have to make implicit to explicit implementations like below .

public bool IsPublished
        {
            get
            {
                return ((IPublishInformation)this).IsPublished;
            }
            set
            {
                ((IPublishInformation)this).IsPublished = value;
            }

        }

bool IPublishInformation.IsPublished { get; set; }
public DateTime CreatedOn 
   { 
       get 
            {
                ((IRecordInformation)this).CreatedOn;
            }
       set
            {
                 ((IRecordInformation)this).CreatedOn = value; 
            }
   }
public DateTime ModifiedOn
   {
         get
              {
                  return ((IRecordInformation)this).ModifiedOn;
              }
         set
              {
                  ((IRecordInformation)this).ModifiedOn = value;
               }

    }
public DateTime IRecordInformation.CreatedOn { get; set; }
public DateTime IRecordInformation.ModifiedOn { get; set; }

Now entity Framework core sees the CreatedOn ModifiedOn properties and creates the corresponding columns in the table .

Question on stackoverflow also 

https://stackoverflow.com/questions/61422152/when-using-explicit-interface-implementation-in-entity-classes-ef-core-does-no/61537924#61537924

ASP.NET MVC Core, C# , , , , , , , ,

How to create a UrlHelperExtension in ASP.NET Core 3 ? How to Enable automatic setting navbar links to active class in bootstrap when the respective page is accessed or shown

25. April 2020

How to create a UrlHelperExtension in ASP.NET Core 3 ? How to Enable automatic setting navbar links to active class in bootstrap when the respective page is accessed or shown

This following example of creating a HelperExtension method is needed for the problem of making navbar links <li> be active when on the respective page . eg: In the following screenshot you can see the bootstrap navbar with some links .

Now we have to make some functionality so that when we are on the Services page then services Link is highlighted with white font-color. In bootstrap this is done by simply adding active class in <li> like this

 

Now to make it automatically done in asp.net core we will use @Url Helper Extension method .

For that create a Folder Helpers and add one class named as UrlHelperExtensions.cs. Add the code below in this file

using Microsoft.CodeAnalysis.CSharp.Syntax;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Routing;

namespace Clanstech.Helpers
{
    
    public static class UrlHelperExtensions
    {
        public static string MakeActive(this IUrlHelper urlHelper,string controller)
        {
            string result = "active";

            string controllerName = urlHelper.ActionContext.RouteData.Values["controller"].ToString();

            if (!controllerName.Equals(controller, StringComparison.OrdinalIgnoreCase))
            {
                result = null;
            }

            return result;
        }
    }
}

Now Add a reference of this class in your _ViewImports.cshtml or You can directly add this in your _Layout.cshtml top of page like this

 

 

Now open the _Layout.cshtml and add the newly created extension helper of Url like this

<li class="nav-item @Url.MakeActive("Home")">
    <a class="nav-link" asp-action="Index" asp-controller="Home" asp-area="Admin">Home <span class='sr-only'>(current)</span></a>
</li>
<li class="nav-item @Url.MakeActive("Services")">
    <a class="nav-link" asp-action="Index" asp-controller="Services" asp-area="Admin">Services </a>
</li>
<li class="nav-item @Url.MakeActive("Pricing")">
     <a class="nav-link" href="#">Pricing </a>
</li>

 

 

 

 

ASP.NET MVC Core , ,

Adding logging to file in ASP.NET MVC Core using Serilog

24. April 2020

Open the Project.csproj file and add the following code

<PackageReference Include="Serilog.Extensions.Logging.File" Version="1.0.1"/>

Or you can open up the nuget Package Manager Console and write this command and press enter 

Install-Package Serilog.Extensions.Logging.File

 Or you can open the Powershell in goto the directory of your project and run this command 

dotnet add package Serilog.Extensions.Logging.File

This will automatically add the dependencies

 

Now open the Startup.cs file add the following code

loggerFactory.AddFile("Logs/myapp-{Date}.txt");

And do remember to add the IloggerFactory loggerFactory parameter in Configure method parameters list . Line mentioning the file path is where the file will be created for logging.

 

 

Add the following code to your controller

public class HomeController : Controller
    {
        private readonly ILogger<HomeController> _logger;
        

        public HomeController(ILogger<HomeController> logger)
        {
            _logger = logger;
        }

        public IActionResult Index()
        {

            _logger.LogInformation("Message displayed : " + $"HomePage visited at {DateTime.UtcNow.ToLongDateString()} , {DateTime.UtcNow.ToLongTimeString()}");
            return View();
        }
}

Now you run the application and whenever you browse to the Index method of Home controller the log file will be appended .

Now check Logs Folder which contains the file with Date suffixed

 

 

ASP.NET MVC Core, Logging, Serilog , ,

How to Get the Base URL in ASP.NET MVC Core View , ASP.NET MVC Core get website link in View

21. April 2020

Get the Absolute URI from ASP.NET MVC Content or Action.

How to Get the Base URL in ASP.NET MVC Core View ?

ASP.NET MVC Core get website link in View .

 

Answer to above questions when i was trying to find what i actually wanted is below .

@Url.Action(<action>,<controller>,null,Context.Request.Scheme)

You can replace the <action> and <controller> with your values in double quotes if you want to get the exact link of a action method .

It will generate a link like - http://www.clanstech.com/Home/Services

Or you can also ignore <action>, <controller> altogether to get just the base url , website link , domain link on which you are hosting your website application .

Like this @Url.Action(null,null,null,Context.Request.Scheme)

It will generate a link like - http://www.clanstech.com/

ASP.NET MVC, ASP.NET MVC Core, C# , , , , ,

Porting HTML5 Template to ASP.NET MVC Core View

20. April 2020

Whenever porting a HTML template to ASP.NET MVC Core view we have to keep in mind that the path for resources like image , css , scripts should always be coded with '/' before the folder name . For Example -

If you have a template named Clanstech with folder structure as  mentioned in below image.

With code in about.html will be like

<link rel="stylesheet" href="assets/css/aos.css">

In order to use the above css file in ASP.NET MVC Core project with the following structure

We will have to use the following code

<link rel="stylesheet" href="/assets/css/aos.css">

If we dint add '/' before assets folder then it will not load the css file if the user is on suppose /localhost:876/Home/About action/page/view.

To get more idea how file path works , below is the correct usage as shown on this link also https://www.w3schools.com/html/html_filepaths.asp

 


HTML File Paths

<img src="picture.jpg"> picture.jpg is located in the same folder as the current page
<img src="images/picture.jpg"> picture.jpg is located in the images folder in the current folder
<img src="/images/picture.jpg"> picture.jpg is located in the images folder at the root of the current web
<img src="../picture.jpg"> picture.jpg is located in the folder one level up from the current folder

ASP.NET MVC Core, HTML5 , ,