Tech Point Fundamentals

Sunday, December 4, 2022

.Net Core Interview Questions and Answers - Part 14

ASP.Net Core Interview Questions and Answers - Part 14

AspDotNetCoreInterviewQuestionsAndAnswers

Are you preparing for the .Net Core Interview? If yes, then you are at the right place. This is the ASP.Net Core Interview Questions and Answers article series. Here we will see the Top 150+ .Net Core Interview Questions with Answers. 

Please visit our YouTube Channel for Interviews and other videos by the below link:




Please read the complete Design Pattern, C#, MVC, WebAPI, and .Net Framework Interview Questions and Answers article series here.




Introduction


This is the 14th part of the .Net Core Interview Questions and Answers article series. Each part contains ten .Net Core Interview Questions. Please read all the .Net Interview Questions list here.

I will highly recommend to please read the previous parts over here before continuing the current part:






ASP.Net Core Interview Questions and Answers - Part 14


Q135. How does logging work in .Net Core? What are the different log providers in .Net Core?

The .Net Core has inbuild support for logging. The .NET Core SDK is a lightweight SDK that includes a bare minimum set of features required to build an application. Microsoft provides .NET APIs as .NET Extensions. 

.NET Extensions is an open-source, cross-platform set of APIs for commonly used programming patterns and utilities, such as dependency injection, logging, and app configuration. All the extensions are included under Microsoft.Extensions namespace.

The Logging API is included in Microsoft.Extensions.Logging package. The Logging API does not work as a standalone. It works with one or more logging providers that store or display logs to a particular medium such as Console, Debug, TraceListeners, etc. Microsoft.Extensions.Logging includes the necessary classes and interfaces for logging like ILogger, ILoggerFactory, ILoggerProvider interfaces, and the LoggerFactory class.

So, there are two important building blocks for implementing logging in a .NET Core: Logging API and Logging Providers. The logging API in Microsoft.Extensions.Logging works on the .NET Core-based applications whether it is ASP.NET Core or EF Core.



ILoggerFactory: The ILoggerFactory is the factory interface for creating an appropriate ILogger type instance and also for adding the ILoggerProvider instance. 

The Logging API includes the built-in LoggerFactory class that implements the ILoggerFactory interface. We can use it to add an instance of type ILoggerProvider and to retrieve the ILogger instance for the specified category.

public interface ILoggerFactory : IDisposable
{
ILogger CreateLogger(string categoryName);
void AddProvider(ILoggerProvider provider);
}

ILogger: The ILogger interface includes methods for logging to the underlying storage. There are many extension methods that make logging easy. 

public interface ILogger
{
void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter);

bool IsEnabled(LogLevel logLevel);
IDisposable BeginScope<TState>(TState state);



ILoggerProvider: The ILoggerProvider manages and creates an appropriate logger, specified by the logging category. We can create our own logging provider by implementing the ILoggerProvider interface. 

public interface ILoggerProvider : IDisposable
{
ILogger CreateLogger(string categoryName);
}

Logging Providers: A logging provider displays or stores logs to a particular medium such as a console, a debugging event, an event log, a trace listener, and others. Microsoft provides various logging providers as NuGet packages.

Microsoft has also collaborated with various logging framework teams (including third parties like NLog, Serilog, Logger, Log4Net, and others) to extend the list of providers compatible with Microsoft.Extensions.Logging.




Q136. What are log levels? What are the different log levels available in .Net Core?

Log levels indicate the importance or severity of log messages and each log level has different Severity. 

public enum LogLevel
{
Trace = 0,
Debug = 1,
Information = 2,
Warning = 3,
Error = 4,
Critical = 5,
}

Built-in log providers include extension methods to indicate log levels.

log-levels

We can use extension methods to indicate the level of the log messages:

ILoggerFactory loggerFactory = new LoggerFactory().AddConsole((_, __) => true);
ILogger logger = loggerFactory.CreateLogger<Program>();

logger.LogError("Log Error info.");
logger.LogWarning("Log Warning info.");



You could specify that by default, Debug or higher level logs are written to providers, but for logs written by services in the Microsoft namespace, only logs of at least Warning level or above are written. With this approach, you can control the amount of logging produced by the various libraries in your application, increasing logging levels for only those areas that need them.

For example, we can filter out Warning logs in the Microsoft namespace but keep other logs at the Debug level. With the default ASP.NET Core 1.X template, all you need to do is change the appsettings.json file, and set the log levels to Warning as appropriate:

{
  "Logging": {
"IncludeScopes": false,
"LogLevel": {
  "Default": "Debug",
  "System": "Warning",
  "Microsoft": "Warning"
}
  }
}

It is a good idea to instrument your code with as many log messages are useful, and you can filter out the most verbose Trace and Debug log levels. These filtering capabilities are a really useful way of cutting through the cruft, but there's one particular downside.

You can check whether the particular log level is enabled for the current logger, before trying to write to it.

if(_logger.IsEnabled(LogLevel.Debug))
{
_logger.LogDebug("Calling HomeController.Index");
}



Q137. How can you configure logging in ASP.Net Core applications? 

ASP.NET Core uses the same logging mechanism as .NET Core logging. When you create the ASP.NET Core MVC web application in Visual Studio 2017 (or later), it automatically includes the NuGet package for Microsoft.Extensions.Logging and some required logging providers (Console, Debug, EventSource, TraceSource) under Microsoft.AspNetCore.App NuGet package. 

To enable Logging in the initial versions of ASP.Net Core (.Net Core 1.x), it is required to add dependency within Project.json or .csproj file and needs some configuration under the startup class to add into DI. Also if we want to add any third-party provider or configure filtering, we need to add a configuration in the startup class. But in the new versions (.Net Core 2.0 and later) of the framework, Logging is added into the DI system by default. 

When you create the ASP.NET Core MVC web application in Visual Studio 2017 (or later), it automatically includes the NuGet package for Microsoft.Extensions.Logging and all the required logging providers (Console, Debug, EventSource, TraceSource) under Microsoft.AspNetCore.App NuGet package.



In the ASP.NET Core MVC application, the call to the WebHost.CreateDefaultBuilder(args) method in the Program.cs internally adds the Console, Debug, and EventSource logging providers.

 public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
   .UseStartup<Startup>();

But if you want to use other providers or any default provider, then you need to remove all the existing providers and add the provider of your choice. To configure logging providers, call the ConfigureLogging() extension method of IWebHostBuilder:

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.ConfigureLogging(logBuilder =>
{
logBuilder.ClearProviders(); 
logBuilder.AddConsole();  
logBuilder.AddTraceSource("Information, ActivityTracing"); 
})
.UseStartup<Startup>();

You can also configure the logging provider using ILoggerFactory in the Configure() method of the Startup class.



Q138. How can you write the log files in the text file in ASP.Net Core applications using logger?

In order to store logs in a file, install the NuGet package Serilog.Extensions.Logging.File. The Serillog includes an extension method for ILoggerFactory but not for ILogBuilder. You can also use log4net as well.

So, go to the Startup.cs file and add the ILoggerFactory parameter in the Configure() method. Then, call the AddFile() extension method to add Serillog file provider:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) 
{
logBuilder.ClearProviders();
loggerFactory.AddFile("Logs/mylog-{Date}.txt");
}




After that, we can use ILogger or ILoggerFactory anywhere in an application using ASP.NET Core DI.

 public class UserController : Controller
{
private readonly ILogger _logger;

public HomeController(ILogger<UserController> logger){
_logger = logger;
}
public IActionResult Index()
{
_logger.LogInformation("Log message in the Index() method");

return View();
}
}

Here passing UserController as the generic type for the ILogger<UserController>, will be used as a category.   When a logger is created, a category name must be provided. The category name specifies the source of the logging events.

After specifying ILogger<UserController> it will display a fully qualified name AspDotNetCoreMvcApp.Controllers.UserController in the logs:

info: AspDoteNetCoreMvcApp.Controllers.UserController[0]
Log message in the Index() method



Q139. What is LoggerMessage in ASP.Net Core? How it is different from Logger?

One of the hidden but powerful features in ASP.NET Core is LoggerMessage, which has reduced overhead compared to the Logger extension methods. The static LoggerMessage class is available in Microsoft.Extensions.Logging.Abstractions package, and contains a number of static, generic Define methods that return an Action<> which in turn can be used to create strongly-typed logging extensions.

LoggerMessage features create cacheable delegates that require fewer object allocations and reduced computational overhead compared to logger extension methods, such as LogInformation() and LogDebug(). For high-performance logging scenarios, use the LoggerMessage pattern.

LoggerMessage vs Logger:

1. Logger extension methods require "boxing" for value types, such as int, into the object. But the LoggerMessage pattern avoids boxing by using static Action fields and extension methods with strongly-typed parameters.

2. Logger extension methods must parse the message template (named format string) every time a log message is written. LoggerMessage only requires parsing a template once when the message is defined.



LoggerHelper.Define() method:

LoggerMessage.Define creates an Action delegate for logging a message. Define() method overloads permit passing up to six type parameters to a named format string (template).

The purpose of the static LoggerMessage.Define<T> method is:

  1. Encapsulate the if statement to allow performant logging
  2. Enforce the correct strongly-typed parameters are passed when logging the message
  3. Ensure the log message contains the correct number of placeholders for parameters

The string provided to the Define method is a template and not an interpolated string. Placeholders are filled in the order that the types are specified. 

Placeholder names in the template should be descriptive and consistent across templates. They serve as property names within structured log data.



public static class LoggerMessage
{
public static Action<ILogger, T1, Exception> Define<T1>( LogLevel logLevel, EventId eventId, string formatString)
{
    var formatter = CreateLogValuesFormatter( formatString, expectedNamedParameterCount: 1);
return (logger, arg1, exception) =>
{
if (logger.IsEnabled(logLevel))
{
ogger.Log(logLevel, eventId, new LogValues<T1>(formatter, arg1), exception,                 LogValues<T1>.Callback);
}
};
}
}

Each log message is an Action held in a static field created by LoggerMessage.Define. The Action is invoked through a strongly-typed extension method. 



Q140. What is the model state? What is the difference between model binding and model validation in ASP.Net MVC Core?

The model state represents errors that come from two subsystems: model binding and model validation.

Errors that originate from model binding are generally data conversion errors, for example, an "x" is entered in an integer field. 

Model validation occurs after model binding and reports errors where data doesn't conform to business rules, for example, a 0 is entered in a field that expects a rating between 1 and 5.
 
Both model binding and model validation occurs before the execution of a controller action or a Razor Pages handler method. 






Q141. What is model validation in ASP.Net Core?

Model Validation is a process to ensure that the data received from the View is appropriate to bind the Model. If it is not, then appropriate error messages are displayed on the View, and that will help the user to rectify the problem.

Model Validation in Web App:

Both model binding and model validation occurs before the execution of a controller action or a Razor Pages handler method. For web apps, it's the app's responsibility to inspect ModelState.IsValid and react appropriately. 

The ModelState.IsValid is a property that returns true if all the model properties are valid and return false otherwise.

if (!ModelState.IsValid)
{
return Page();
}

Model Validation feature adds the CSS class called input-validation-error to all the controls that have failed the validation checks i.e. whenever some error message is recorded for a property by the method – ModelState.AddModelError().



Model Validation in ASP.NET Core REST API:

To implement model validation in an ASP.NET Core REST API, just decorate the respective properties with the validation attributes. Web API controllers don't have to check ModelState.IsValid if they have the [ApiController] attribute. In that case, an automatic HTTP 400 response containing error details is returned when a model state is invalid. 

In an ASP.NET Core REST API, there is no need to explicitly check if the model state is valid. Since the controller class is decorated with the [ApiController] attribute, it takes care of checking if the model state is valid and automatically returns 400 responses along with the validation errors.



Returning Custom Validations by using TryValidateModel():

Validation is automatic, but you might want to repeat it manually. Sometimes you want to check. For example, you might compute a value for a property and want to re-run validation after setting the property to the computed value. 

To rerun validation, call ModelStateDictionary.ClearValidationState to clear validation specific to the model being validated followed by TryValidateModel:

 ModelState.ClearValidationState(nameof(Employee));
if (!TryValidateModel(Employee, nameof(Employee)))
{
return Page();
}






Q142. What is Model Level Error Message in ASP.Net Core? How can you add a custom model error?

Adding Custom Model Error:

To add a custom model validation error, use AddModelError() method of the ModelState object. The AddModelError() method is used to record a Model Validation error for a specified property.

var user = employeeRepository.GetEmployeeByEmail(employee.Email);
if(user != null)
{
ModelState.AddModelError("email", "User email already in use");
return BadRequest(ModelState);
}



Model-Level Error Messages:

Model-Level Error Messages are those that are applicable to the model as a whole and not to individual properties. You can apply then providing an empty string (“”) to the property parameter of the AddModelError() method:

ModelState.AddModelError("", "Some Model-Level error"); 

Also, you need to go to the Index View and change the asp-validation-summary to ModelOnly:

<div asp-validation-summary="ModelOnly" class="text-danger"></div>



Q143. How can you create a Custom Model Validation Attribute in ASP.Net Core?

You can also create your own Custom Model Validation Attribute that does the validation of values in the manner defined by you. The Custom Validator is very powerful, you can create validation for names preventing some users with a particular name or any other things as well. 

For this you have to create a class and inherit it from 2 classes: Attribute and IModelValidator.

The IModelValidator interface defines Validate() method which you have to implement in your class. In this method, you write your custom validation logic.

Inside this method, you receive information about the property (that is to be validated) through an instance of the ModelValidationContext class.

The ModelValidationContext class contains three properties: Model, Container, and ActionContext. The Model returns the property value that is to be validated while Container returns the object that contains the property. The ActionContext provides the context data.



namespace CustomModelBindingValidation.Infrastructure
{
public class CustomDate : Attribute, IModelValidator
{
public IEnumerable<ModelValidationResult> Validate(ModelValidationContext context)
{
 
if (Convert.ToDateTime(context.Model) > DateTime.Now)
return new List<ModelValidationResult> {
new ModelValidationResult("", "Date of Birth cannot be in the future")
};
else if (Convert.ToDateTime(context.Model) < new DateTime(1980, 1, 1))
return new List<ModelValidationResult> {
new ModelValidationResult("", "Date of Birth should not be before 1980")
};
else
return Enumerable.Empty<ModelValidationResult>();
}
}
}

After this you can use this for any DateTime fields:

[CustomDate]
public DateTime DOB { get; set; }



Q144. What is the Validation attribute? What are Data Annotations? 

Validation attributes let you specify validation rules for model properties. There is another way to do Model Validations which is by the use of Validation Attributes in the Model class. This process is known as Model Validation from Data Annotation and is very easy, fast, and removes code duplication.

ASP.NET Core provides several built-in attributes for model validation.  The complete list of validation attributes can be found in the System.ComponentModel.DataAnnotations namespace. 






To Be Continued Part-15...


Recommended Articles






Thanks for visiting this page. Please follow and join us on LinkedInFacebookTelegramQuoraYouTubeTwitterPinterestTumbler, and VK for regular updates.

    

No comments:

Post a Comment

Please do not enter any HTML. JavaScript or spam link in the comment box.