Monday 28 September 2020

ASP.NET Core - Serving Static files

 Here, we will learn how to serve static files such as html, JavaScript, CSS, or image files on HTTP request without any server-side processing.

ASP.NET Core application cannot serve static files by default. We must include Microsoft.AspNetCore.StaticFiles middleware in the request pipeline.

Using StaticFiles Middleware

By default, all the static files of a web application should be located in the web root folder wwwroot. To understand this, let's create a simple default.html in the wwwroot folder with the following content.

Now, to serve the above Default.html static file, we must add StaticFiles middleware in the Configure() method of Startup file as shown below.
public class Startup
{
    public Startup()
    {
    } 
 
    public void Configure(IApplicationBuilder appIHostingEnvironment env)
    {
        app.UseStaticFiles();

        app.Run(async (context=>
        {
            await context.Response.WriteAsync("Hello World");
        });
    }
}

As you can see above, the app.UseStaticFiles() method adds StaticFiles middleware into the request pipeline. The UseStaticFiles is an extension method included in the StaticFiles middleware so that we can easily configure it.

Now, open the browser and send http request http://localhost:<port>/default.html which will display default.html as a response as shown below.

Serving HTML File

This way we can serve any other file stored in wwwroot folder or sub-folder.

Suppose, you want to serve files from the outside of web root folder (wwwroot). For example, you include images in the following Images folder as shown below.


Now, specify StaticFileOptions parameter in the UseStaticFiles method to serve images from the Images folder as shown below.
public void Configure(IApplicationBuilder appIHostingEnvironment env)
{
    app.UseStaticFiles(); // For the wwwroot folder

    app.UseStaticFiles(new StaticFileOptions()
    {
        FileProvider = new PhysicalFileProvider(
                            Path.Combine(Directory.GetCurrentDirectory(), @"Images")),
                            RequestPath = new PathString("/app-images")
    });
}

As you can see, we used FileProvider option to specify Images folder from which static files will be served. The RequestPath option specifies the relative path in the URL which maps to the static folder.

Now, a request to http://localhost/app-images/MyImage.png will serve the MyImage.png file.

Set Default File

As we have seen above, default.html or test.js was served on the specific request for it. However, what if we want to serve default html file on the root request?

Currently, when you send http://localhost:<port> request, it will be handled by run method and display the following result.

To serve default.html on the root request http://localhost:<port>, call UseDefaultFiles() method before UseStaticFiles() in the Configure method as shown below.

public void Configure(IApplicationBuilder appIHostingEnvironment env)
{
    app.UseDefaultFiles();
    app.UseStaticFiles();

    app.Run(async (context=>
    {
       await context.Response.WriteAsync("Hello World");
    });
}

The UseDefaultFiles configures the DefaultFiles middleware which is a part of StaticFiles middleware. This will automatically serve html file named default.html, default.htm, index.html or index.htm on the http request http://localhost:<port>. The above example will display default.html file on http://localhost:<port> request.

Note:- Order of middleware is very important. app.UseDefaultFiles() should be added before app.UseStaticFiles() in the request pipeline.

FileServer

The FileServer middleware combines the functionalities of UseDefaultFiles and UseStaticFiles middlware. So, instead of using both the middlware, just use UseFileServer in the Configure method.

UseFileServer = UseDefaultFiles + UseStaticFiles

Thus, we can serve static files on http requests.

Reference: www.tutorialsteacher.comhttps://docs.microsoft.com

Continue Reading →

ASP.NET Core - Exception Handling

Exception handling is one of the most important features of any application. Fortunately, ASP.NET Core includes a middleware that makes exception handling easy. 

By default, ASP.NET Core returns a simple status code for any exception that occurs in an application. Consider the following example of Configure method which throws an error.

public class Startup
{
    public void Configure(IApplicationBuilder appIHostingEnvironment env)
    {            
        app.Run(context => { throw new Exception("error"); });
    }
}

The above code will display the following result.


Install Microsoft.AspNetCore.Diagnostics Package

To handle exceptions and display user friendly messages, we need to install Microsoft.AspNetCore.Diagnostics NuGet package and add middleware in the Configure() method. If you are using Visual Studio templates to create ASP.NET Core application then this package might be already installed. If not then you can add Microsoft.AspNetCore.Diagnostics package via NuGet manager.

The Microsoft.AspNetCore.Diagnostics package includes following extension methods to handle exceptions in different scenario:

  1. UseDeveloperExceptionPage
  2. UseExceptionHandler

UseDeveloperExceptionPage

The UseDeveloperExceptionPage extension method adds middleware into the request pipeline which displays developer friendly exception detail page. This helps developers in tracing errors that occur during development phase.

As this middleware displays sensitive information, it is advisable to add it only in development environment.

UseExceptionHandler

In MVC Core application, we might want some other controller to handle all exceptions and display custom user friendly error messages. The UseExceptionHandler extension method allows us to configure custom error handling route. This is useful when an application runs under production environment.

public void Configure(IApplicationBuilder appIHostingEnvironment env)
{

    if (env.IsDevelopment() || env.IsStaging())
    {
        app.UseDeveloperExceptionPage();
    }
    else 
    {
        app.UseExceptionHandler("/Home/Error");
    }

    //code removed for clarity 
}

In the above example, the UseExceptionHandler("/Home/Error") sets the error handler path. If an error occurred in the MVC application then it will redirect the request to /home/error, which will execute the Error action method of HomeController In case of Production environment.

Exception filters

In MVC apps, exception filters can be configured globally or on a per-controller or per-action basis. In Razor Pages apps, they can be configured globally or per page model. These filters handle any unhandled exception that occurs during the execution of a controller action or another filter. For more information, see Filters in ASP.NET Core.

Refrence: https://www.tutorialsteacher.com/https://docs.microsoft.com


Continue Reading →

Sunday 27 September 2020

ASP.NET Core MVC: Routing

 What is Routing in ASP.NET Core MVC?

Routing is the process through which the application matches an incoming URL path and executes the corresponding action methods. ASP.NET Core MVC uses a routing middleware to match the URLs of incoming requests and map them to specific action methods.

So, the ASP.NET Core Framework maps the incoming Requests i.e. URLs to the Controllers action methods based on the routes configured in your application. You can configure multiple routes for your application and for each route you can also set some specific configurations such as default values, constraints, message handlers, etc.

There are two types of routing for action methods:

  1. Conventional Routing
  2. Attribute Routing

In Conventional Based Routing, the route is determined based on the conventions defined in the route templates which will map the incoming Requests (i.e. URLs) to controllers and their action methods. In ASP.NET Core MVC application, the Convention based Routes are defined within the Configure method of the Startup.cs class file.

In Attribute-Based Routing, the route is determined based on the attributes which are configured either at the controller level or at the action method level. We can use both Conventional Based Routing and Attribute-Based Routing in a single application.

Understanding the Default Route in ASP.NET Core MVC Application:

 We can add the required MVC middleware into the request processing pipeline either by calling the UseMvcWithDefaultRoute() method or by calling the UseMvc() method within in the Configure() method of the Startup.cs class file as shown in the below code. As of now, we are using the UseMvcWithDefaultRoute() middleware.

public void Configure(IApplicationBuilder app) { 
    
    app.UseDeveloperExceptionPage(); 
    app.UseFileServer(); 
    app.UseMvcWithDefaultRoute();   
}

Let us have a look at the implementation of the UseMvcWithDefaultRoute() method by visiting the following GitHub URL.

As you can see in the above implementation, this method internally calls the UseMvc() method which will add the default route into the application’s request processing pipeline. 

Understanding The Route Template:

The above default route template maps most URLs that have the following pattern.

http://localhost:52190/Student/Details/2
http://localhost:52190/Student/Details

This gives us a default routing rule that allows us to get to the HomeController. Instead of using the UseMvcWithDefaultRoute, let us use the UseMvc, and then configure the route at this point using a named method ConfigureRoute. The following is the implementation of the Startup.cs file.

     
     public void ConfigureServices(IServiceCollection services) { 
         services.AddMvc(); 
      }  
        
      // This method gets called by the runtime.  
      // Use this method to configure the HTTP request pipeline. 
      public void Configure(IApplicationBuilder app) { 
         app.UseDeveloperExceptionPage(); 
         app.UseFileServer(); 

         app.UseMvc(ConfigureRoute);  
      } 
 
      private void ConfigureRoute(IRouteBuilder routeBuilder) { 
         //Home/Index 
       routeBuilder.MapRoute("Default""{controller = Home}/{action = Index}/{id?}");
      } 

Inside the ConfigureRoute method, you can configure your routes; you can see that this method has to take a parameter of type IRouteBuilder. The goal of routing is to describe the rules that ASP.NET Core MVC will use to process an HTTP request and find a controller that can respond to that request.

When using attribute-based routing you would mention route on your controller or the action method. You can define multiple routes for the same action method. Here is an example that illustrates this.

public class HomeController : Controller
{
    [Route("")]
    [Route("Home")]
    [Route("Home/Index")]
    public IActionResult Index()
    {
        return View();
    }
     [Route("Home/GetAuthor/{id:int}")]
    public IActionResult GetAuthor(int id)
    {
        ViewBag.Id = id;
        return View();
    }
}


Use endpoint routing in ASP.NET Core 3.0 MVC

Endpoint routing is a feature newly introduced in ASP.NET Core 3.0 that enables you to provide routing information to middleware in the request processing pipeline.
    Before the introduction of endpoint routing, routing resolution in ASP.NET Core MVC was performed at the end of the request processing pipeline.
As a result, route information (such as which action method needs to be executed) was unknown to any middleware processing a request before the MVC middleware in the request processing pipeline. 

Route definitions in ASP.NET Core 3.0 MVC

When you create a new ASP.NET Core 3.0 MVC application, a default route will be created for you by Visual Studio. This is how it would look.

app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllerRoute(
            name"default",
            pattern"{controller=Home}/{action=Index}/{id?}");
    }

The route definition shown here consists of two parameters — the name of the route and the route pattern. This route will match the following URLs.

/Home/Index
/Author/Index
/Author/Index/12

Note that the UseRouting middleware should be configured ahead of all other middleware including authentication, authorization, and any custom middleware. By contrast, the UseEndpoints middleware should be configured at the end. The following code snippet illustrates this.

public void Configure(IApplicationBuilder appIWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
            }
            app.UseStaticFiles();
            app.UseRouting();
            app.UseAuthorization();
            app.UseEndpoints(endpoints =>
            {
               endpoints.MapControllerRoute(
               name"default",
               pattern"{controller=Author}/{action=GetAuthor}/{id?}");
            });
        }

Inside the call to UseEndpoints, MapControllerRoute is used to create a single route. The single route is named default route. Most apps with controllers and views use a route template similar to the default route. REST APIs should use attribute routing.

Multiple conventional routes

Multiple conventional routes can be added inside UseEndpoints by adding more calls to MapControllerRoute and MapAreaControllerRoute. Doing so allows defining multiple conventions, or to adding conventional routes that are dedicated to a specific action, such as:

app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllerRoute(name"blog",
                    pattern"blog/{*article}",
                    defaultsnew { controller = "Blog"action = "Article" });
        endpoints.MapControllerRoute(name"default",
                    pattern"{controller=Home}/{action=Index}/{id?}");
    });

The blog route in the preceding code is a dedicated conventional route.

Important: 

Routing is configured using the UseRouting and UseEndpoints middleware. To use controllers:

  • Call MapControllers inside UseEndpoints to map attribute routed controllers.
  • Call MapControllerRoute or MapAreaControllerRoute, to map both conventionally routed controllers and attribute routed controllers.

Refrence: https://dotnettutorials.nethttps://www.infoworld.comhttps://docs.microsoft.com


Continue Reading →

ASP.NET Core - Logging

 .NET Core supports a logging API that works with a variety of built-in and third-party logging providers. This article shows how to use the logging API with built-in providers.

Logging providers

Logging providers store logs, except for the Console provider which displays logs. For example, the Azure Application Insights provider stores logs in Azure Application Insights. Multiple providers can be enabled

Add Logging Providers

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

  1. Console
  2. Debug
  3. EventSource 

public class Program
{
    public static void Main(string[] args)
    {
        CreateWebHostBuilder(args).Build().Run();
    }

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

Look at the source code of the WebHost.CreateDefaultBuilder() method on GitHub and you will find the following code:

.ConfigureLogging((hostingContextlogging=>
    {
        logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
        logging.AddConsole();
        logging.AddDebug();
        logging.AddEventSourceLogger();
    }).

Thus, if you want to use these providers, no need to add them manually. If you want to override the  existing log 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, as shown below.

public static IWebHostBuilder CreateWebHostBuilder(string[] args=>
    WebHost.CreateDefaultBuilder(args)
    .ConfigureLogging(logBuilder =>
    {
        logBuilder.ClearProviders(); // removes all providers from LoggerFactory
        logBuilder.AddConsole();  

        // Add Trace listener provider
        logBuilder.AddTraceSource("Information, ActivityTracing"); 
    })
.UseStartup<Startup>();

You can also configure the logging provider using ILoggerFactory in the Configure() method of the Startup class. Let's see an example on how to store logs in a text file.

Store Logs in a Text File 

To store logs in a file, install the NuGet package Serilog.Extensions.Logging.File. Serillog includes an extension method for ILoggerFactory but not for ILogBuilder (in v 1.1.0). 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, as shown below. ASP.NET Core dependency injection will automatically pass an instance of the LoggerFactory for this parameter.

public void Configure(IApplicationBuilder appIHostingEnvironment env,
ILoggerFactory loggerFactory
{
    // other code remove for clarity 
    loggerFactory.AddFile("Logs/errorlog-{Date}.txt");
}

This will store all the logs in the errorlog-<date>.txt file, under the Logs folder in your application.

Create Logs in the Controller

We can use ILogger or ILoggerFactory anywhere in an application using ASP.NET Core DI (Dependency Injection). Consider the following example of HomeController:

namespace AspDotNetCoreMvcApp.Controllers
{
    public class HomeController : Controller
    {
        private readonly ILogger _logger;

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

            return View();
        }

        public IActionResult About()
        {
            _logger.LogInformation("Log message in the About() method");
            
            return View();
        }
    }
}

In the above example, the ILogger<HomeController> parameter is included in the constructor. ASP.NET Core DI will pass the ILogger instance, which can be used to log in the Index() and About() action methods.

Passing HomeController as generic type for the ILogger<HomeController>, will be used as a category. For example, specifying ILogger<HomeController> will display a fully qualified name AspDotNetCoreMvcApp.Controllers.HomeController in the logs, as shown below.

infoAspDoteNetCoreMvcApp.Controllers.HomeController[0]
Log message in the Index() method

Let's understand the above log message. Here, we logged information using the LogInformation() method, so it starts with "info:" followed by the fully qualified name of the class where a log is created: AspDoteNetCoreMvcApp.Controllers.HomeController[0]. [0] is the event id. You can specify this event id to identify a record, e.g. Id, page number or other important information which uniquely identifies a log. We didn't specify any event id, so it will be 0. The next line is an actual log message: "Log message in the Index() method".

The same can be achieved by passing ILoggerFactory in the constructor.

public class HomeController : Controller
{
    private readonly ILogger _logger;

    public HomeController(ILoggerFactory logFactory
    {
        _logger = logFactory.CreateLogger<HomeController>();
    }
        
    public IActionResult Index()
    {
        _logger.LogInformation("Log message in the Index() method");

        return View();
    }
}

You will get same logging information. Thus, we can implement logging in ASP.NET Core MVC application.

Refrence: https://docs.microsoft.comhttps://www.tutorialsteacher.com/

Continue Reading →

ASP.NET Core: Environment Variable

 Typically, in professional application development, there are multiple phases where an application is tested before publishing it to the real users. These phases by convention are development, staging, and production. We as developers might like to control the behavior of an application based on the phases the application is in. Environment variable indicates the runtime environment in which an application is currently running.

ASP.NET Core uses an environment variable called ASPNETCORE_ENVIRONMENT to indicate the runtime environment. The value of this variable can be anything as per your need but typically it can be Development, Staging, or Production. The value is case insensitive in Windows and Mac OS but it is case sensitive on Linux.

  1. Development : The launchSettings.json file sets ASPNETCORE_ENVIRONMENT to Development on the local machine.
  2. Staging
  3. Production : The default if DOTNET_ENVIRONMENT and ASPNETCORE_ENVIRONMENT have not been set.
In Visual Studio, we can set ASPNETCORE_ENVIRONMENT in the debug tab of project properties. Open project properties by right clicking on the project in the solution explorer and select Properties.

Environment Variable

You may change the value as per your need. This value will be saved in the launchSettings.json file as shown below.

launchsettings.json

You may also change the environment variable directly in launchSettings.json.

Access Environment Variable at Runtime
We can get the value of an environment variable in our code to execute some additional code based on its value. The IHostingEnvironment service includes EnvironmentName property which contains the value of ASPNETCORE_ENVIRONMENT variable. ASP.NET Core also includes extension methods to check the environment such as IsDevelopment(), IsStating(), IsEnvironment() and IsProduction().

The IHostingEnvironment service is provided by ASP.NET hosting layer and can be used anywhere in your application via Dependency Injection. The following example shows how we can check the environment variable in the Configure method of Startup class.

public void Configure(IApplicationBuilder appIHostingEnvironment env)
{
    if (env.IsEnvironment("Development"))
    {
        // code to be executed in development environment 

    }

    if (env.IsDevelopment())
    {
        // code to be executed in development environment 
app.UseDeveloperExceptionPage();

    }

    if (env.IsStaging())
    {
        // code to be executed in staging environment 
app.UseExceptionHandler("/Error");

    }


    if (env.IsProduction() || env.IsStaging() || env.IsEnvironment("Staging_2"))
    {
// code to be executed in staging, production or staging2 environment 
        app.UseExceptionHandler("/Error");
    }

     app.UseHttpsRedirection();
     app.UseStaticFiles();

     app.UseRouting();

     app.UseAuthorization();



Continue Reading →

Saturday 26 September 2020

Order of execution of a SQL Query

When we have an idea of all the parts of sql query, we can now talk about how they all fit together in the context of a complete query.

SELECT DISTINCT columnAGG_FUNC(column_or_expression), …
FROM mytable
    JOIN another_table
      ON mytable.column = another_table.column
    WHERE constraint_expression
    GROUP BY column
    HAVING constraint_expression
    ORDER BY column ASC/DESC
    LIMIT count OFFSET COUNT;

Each query begins with finding the data that we need in a database, and then filtering that data down into something that can be processed and understood as quickly as possible. Because each part of the query is executed sequentially, it's important to understand the order of execution so that you know what results are accessible where.

Query order of execution

1. FROM and JOINs

The FROM clause, and subsequent JOINs are first executed to determine the total working set of data that is being queried. This includes subqueries in this clause, and can cause temporary tables to be created under the hood containing all the columns and rows of the tables being joined.

2. WHERE

Once we have the total working set of data, the first-pass WHERE constraints are applied to the individual rows, and rows that do not satisfy the constraint are discarded. Each of the constraints can only access columns directly from the tables requested in the FROM clause. Aliases in the SELECT part of the query are not accessible in most databases since they may include expressions dependent on parts of the query that have not yet executed.

3. GROUP BY

The remaining rows after the WHERE constraints are applied are then grouped based on common values in the column specified in the GROUP BY clause. As a result of the grouping, there will only be as many rows as there are unique values in that column. Implicitly, this means that you should only need to use this when you have aggregate functions in your query.

4. HAVING

If the query has a GROUP BY clause, then the constraints in the HAVING clause are then applied to the grouped rows, discard the grouped rows that don't satisfy the constraint. Like the WHERE clause, aliases are also not accessible from this step in most databases.

5. SELECT

Any expressions in the SELECT part of the query are finally computed.

6. DISTINCT

Of the remaining rows, rows with duplicate values in the column marked as DISTINCT will be discarded.

7. ORDER BY

If an order is specified by the ORDER BY clause, the rows are then sorted by the specified data in either ascending or descending order. Since all the expressions in the SELECT part of the query have been computed, you can reference aliases in this clause.

8. LIMIT / OFFSET

Finally, the rows that fall outside the range specified by the LIMIT and OFFSET are discarded, leaving the final set of rows to be returned from the query.

Reference: https://sqlbolt.com/

Continue Reading →

Unit Testing in C#

 What do you mean by a Unit test ?

In the software development process Unit Tests basically test individual parts of code (mostly methods) and make it work as expected by programmer. A Unit Test is a code written by any programmer which test small pieces of functionality of big programs.

Why do we need Unit test?

One of the most valuable benefits of using Unit Tests for your development is that it may give you positive confidence that your code will work as you have expected it to work in your development process. 

One of the fundamental principles of adopting unit testing is to follow a TDD (Test Driven Development) aproach where we have to write tests case first, and then write the simple code that will make the test pass.

We can use MS Unit tests, nUnit for creating Test methods. Below is an example of MS Unit test code.

Code to be tested

public class BasicMaths {  
    public double Add(double num1double num2) {  
        return num1 + num2;  
    }   

Test method for above code testing

[TestClass]  
public class UnitTest1 {  
    [TestMethod]  
    public void Test_AddMethod() {  
            BasicMaths bm = new BasicMaths();  
            double res = bm.Add(1010);  
            Assert.AreEqual(res20);  
        }  
}  


What is Mocking?

Mocking is primarily used in unit testing. An object under test may have dependencies on other (complex) objects. To isolate the behavior of the object you want to replace the other objects by mocks that simulate the behavior of the real objects. This is useful if the real objects are impractical to incorporate into the unit test.

In short, mocking is creating objects that simulate the behavior of real objects.

Moq Framework

Moq is an open-source framework which can be found on GitHub. When start using Moq make sure you always install the very latest version.

When using Moq or any other mocking framework keep following restrictions in mind. You can not mock:

  1. Static class/methods.
  2. Extensions Methods.
  3. Non-virtual methods (except there is an interface).
How to Use Moq to Ease Unit Testing https://dzone.com/

Continue Reading →

What Is Load Balancing

 What Is Load Balancing?

Load balancing is the process of distributing network traffic across multiple servers. This ensures no single server bears too much demand. By spreading the work evenly, load balancing improves application responsiveness. It also increases availability of applications and websites for users. Modern applications cannot run without load balancers.

A load balancer acts as the “traffic cop” sitting in front of your servers and routing client requests across all servers capable of fulfilling those requests in a manner that maximizes speed and capacity utilization and ensures that no one server is overworked, which could degrade performance. If a single server goes down, the load balancer redirects traffic to the remaining online servers. When a new server is added to the server group, the load balancer automatically starts to send requests to it.

In this manner, a load balancer performs the following functions:

  1. Distributes client requests or network load efficiently across multiple servers
  2. Ensures high availability and reliability by sending requests only to servers that are online
  3. Provides the flexibility to add or subtract servers as demand dictates
Question: There is a website run by 2 servers. These 2 servers balances the load using Load Balancer. So, if 1 session is created on 1 server and say load is shift to another server immediately, then how session is maintained?

This is where the concept of "Sticky Sessions" or "Session Affinity" comes into play.

Sticky Sessions: By default, a Classic Load Balancer routes each request independently to the registered instance with the smallest load. However, you can use the sticky session feature (also known as session affinity), which enables the load balancer to bind a user's session to a specific instance. This ensures that all requests from the user during the session are sent to the same instance. Read more

In .Net there are two concepts called StateServer or SQLServer which are the recommendations to get the session information out of the execution process in the servers, so that's the idea, isolate the sessions in a different server or process, you can read a little bit here:

Continue Reading →

Thursday 24 September 2020

ASP.NET Core - Middleware

 ASP.NET Core introduced a new concept called Middleware. A middleware is nothing but a component (class) which is executed on every request in ASP.NET Core application. In the classic ASP.NET, HttpHandlers and HttpModules were part of request pipeline. Middleware is similar to HttpHandlers and HttpModules where both needs to be configured and executed in each request.

Typically, there will be multiple middleware in ASP.NET Core web application. It can be either framework provided middleware, added via NuGet or your own custom middleware. We can set the order of middleware execution in the request pipeline. Each middleware adds or modifies http request and optionally passes control to the next middleware component. The following figure illustrates the execution of middleware components.


Middleware's build the request pipeline. The following figure illustrates the ASP.NET Core request processing.

Configure Middleware

We can configure middleware in the Configure method of the Startup class using IApplicationBuilder instance. The following example adds a single middleware using Run method which returns a string "Hello, World!" on each request.

public class Startup
{
    public void Configure(IApplicationBuilder app)
    {
        app.Run(async context =>
        {
            await context.Response.WriteAsync("Hello, World!");
        });
    }
}

In the above example, Run() is an extension method on IApplicationBuilder instance which adds a terminal middleware to the application's request pipeline. The above configured middleware returns a response with a string "Hello World!" for each request.

To configure multiple middleware, use Use() extension method. It is similar to Run() method except that it includes next parameter to invoke next middleware in the sequence. Consider the following example.

public void Configure(IApplicationBuilder appIHostingEnvironment env)
{
    app.Use(async (contextnext=>
    {
        await context.Response.WriteAsync("Hello World From 1st Middleware!");

        await next();
    });

    app.Run(async (context=>
    {
        await context.Response.WriteAsync("Hello World From 2nd Middleware"); 
    });
}

The above example will display Hello World From 1st Middleware!Hello World From 2nd Middleware! in the browser.

Thus, we can use Use() method to configure multiple middlewares in the order we like.

Add Built-in Middleware Via NuGet

ASP.NET Core is a modular framework. We can add server side features we need in our application by installing different plug-ins via NuGet. There are many middleware plug-ins available which can be used in our application.

The followings are some built-in middleware:

1. Exception Handling:

  • UseDeveloperExceptionPage() & UseDatabaseErrorPage(): used in development phase to catch run-time exceptions.
  • UseExceptionHandler("/Error"): used in production for run-time exceptions

Calling these methods first ensures that exceptions are caught.

2. HSTS & HTTPS Redirection:

  • UseHsts(): HTTP Strict Transport Security Protocol (HSTS) Middleware (UseHsts) adds the Strict-Transport-Security header.
  • UseHttpsRedirection(): forces HTTP calls to automatically redirect to equivalent HTTPS addresses.

Calling these methods next ensure that HTTPS can be enforced before resources are served from a web browser.

3. Static files:

  • UseStaticFiles(): used to enable static files, such as HTML, JavaScript, CSS and graphics files.

This Middleware is called early on to avoid the need for authentication, session or MVC middleware.

4. Cookie Policy:

  • UseCookiePolicy(): used to enforce cookie policy and display GDPR-friendly messaging

5. Authentication, Authorization & Sessions:

  • UseAuthentication(): used to enable authentication and then subsequently allow authorization.
  • UserSession(): manually added to the Startup file to enable the Session middleware.

Calling these after cookie authentication (but before the MVC middleware) ensures that cookies can be issued as necessary and that the user can be authenticated before the MVC engine kicks in.

6. MVC & Routing:

  • UseMvc(): enables the use of MVC in your web application, with the ability to customize routes for your MVC application and set other options.
  • routes.MapRoute(): set the default route and any custom routes when using MVC.
Middleware Ordering
 
Middleware components are executed in the order they are added to the pipeline and care should be taken to add the middleware in the right order otherwise the application may not function as expected. This ordering is critical for security, performance, and functionality.
 
The following middleware components are for common app scenarios in the recommended order:


The first configured middleware has received the request, modify it (if required), and passes control to the next middleware. Similarly, the first middleware is executed at the last while processing a response. That’s why Exception-handling delegates need to be called early in the pipeline, so they can validate the result and displays a possible exception in a browser and client-friendly way.




Reference: https://medium.com/https://docs.microsoft.com


Continue Reading →

Wednesday 23 September 2020

ASP.NET Core Startup Class

Global.asax is no more in ASP.NET Core application. Startup.cs file is a replacement of Global.asax file in ASP.NET Core. Startup class triggers at first when application launches.

The Startup class is a place where:

  1. Services are configured which are required by the application .
  2. The app's request handling pipeline is defined, as a series of middleware components.

Description.
Startup.cs is mandatory in the application, it can be decorated with any access modifier like public, private, internal. multiple Startup classes are allowed in a single application. ASP.NET Core will select the appropriate class based on its Enviroment.

If a class Startup{EnvironmentName} exists, that class will be called for that EnvironmentName.
Should we need to define class name with startup.cs? No it is not necessary that class name should be Startup.
We can define two method in startup file like ConfigureServices and Configure.

public class Startup
{
    // Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
    …
    }
    
    // Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app)
    {
    …
    }
}

ConfigureServices Method :
This is an optional method in Startup class which is used to configure services for application. when any request come to application ConfigureService method will be called first.
ConfigureServices method includes IServiceCollection parameter to register services. This method must be declared with a public access modifier, so that environment will be able to read the content from metadata.
ASP.net core has built-in support for Dependency Injection. We can add services to DI container using this method. Following are ways to define ConfigureServices method in startup class.

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

Configure Method :
The Configure method is used to specify how the application will respond in each HTTP request. this method is mostly used for registering middleware in HTTP pipeline. this method method accept IApplicationBuilder parameter along with some other services like IHostingEnvironment and ILoggerFactory. Once we add some service in ConfigureService method, it will be available to Configure method to be used.

public void Configure(IApplicationBuilder app)
{
app.UseMvc();
}

Above example shows to enable MVC feature in our framework we need to register UseMvc() into Configure and also need to register service AddMvc() into ConfigureServices.

Continue Reading →

Thursday 10 September 2020

ASP.NET State Server

 How to Store Session Data in ASP.NET State Server

ASP.NET Session State allows four modes to specify where you want to store session data: InProc, SQLServer, State Server and Custom. Default mode InProc, is fastest and default mode, but not useful in many scenarios. One of the significant problems is that sessions stored InProc are deleted every time when application restarts. This could happen pretty often.

If your user was in the middle of long task like populating long order form or survey; or reading of license agreement etc., all his previously saved session data will be lost, and he or she must start process from the beginning.

Also, default InProc mode doesn't support multiple servers (web farms) and multiple processors (web gardens). If your website is running on multiple web servers or multiple processors, you have to keep sessions out of ASP.NET process.

As solution for all of these problems, as more reliable and scalable options, ASP.NET introduces State Server and SQL Server. Both State Server and SQL Server stores sessions outside of ASP.NET process, so they are appropriate solution for web farm scenario.

What is ASP.NET State Server?

State Server is implemented as Windows service. File of State Server is aspnet_state.exe. This file is located on [SystemFolder]\Microsoft.Net\Framework\[.Net Framework Version Number]\aspnet_state.exe. Example location for ASP.NET 4.0 could be:

C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_state.exe

How to use Session State service

First, be sure that State Server windows service is running. Check in Windows Control Panel --> Services and assure that "ASP.NET State Service" is started. You can also start state service using command prompt with line:

 net start aspstate 

By default, State Server service is set up to start manually. Change startup type to Automatic so it will run again if computer restarts.

Second step is to edit <sessionState> element in web.config to configure ASP.NET web application to use State Server. Like this:

<sessionState mode="StateServer"  stateConnectionString="tcpip=127.0.0.1:42424" />

That is all. Now you can start ASP.NET application and session data will be stored out of application process, in State Server.

Reference1, Reference2

Continue Reading →

Topics

ADFS (1) ADO .Net (1) Ajax (1) Angular (43) Angular Js (15) ASP .Net (14) Authentication (4) Azure (3) Breeze.js (1) C# (47) CD (1) CI (2) CloudComputing (2) Coding (7) CQRS (1) CSS (2) Design_Pattern (6) DevOps (4) DI (3) Dotnet (8) DotnetCore (16) Entity Framework (2) ExpressJS (4) Html (4) IIS (1) Javascript (17) Jquery (8) Lamda (3) Linq (11) microservice (3) Mongodb (1) MVC (46) NodeJS (8) React (11) SDLC (1) Sql Server (32) SSIS (3) SSO (1) TypeScript (1) UI (1) UnitTest (1) WCF (14) Web Api (15) Web Service (1) XMl (1)

Dotnet Guru Archives