Complete Tutorial on Developing Custom Middleware in ASP.NET Core MVC:
Middleware plays a crucial role in
handling requests and responses in an ASP.NET Core application. This
comprehensive tutorial will guide you through the process of creating custom
middleware in an ASP.NET Core MVC application, using a practical example to
demonstrate key concepts.
1.
Introduction
Middleware in ASP.NET Core is a
software component that is executed on each request. It can be used to handle
various concerns like authentication, logging, error handling, and more.
Middleware components form a pipeline, and each component can process requests,
generate responses, and call the next middleware in the sequence.
2.
Setting Up the Project
- Create a New ASP.NET Core MVC Project:
- Open Visual Studio and create a new project.
- Select "ASP.NET Core Web Application" and
click "Next".
- Name your project (e.g.,
"CustomMiddlewareExample"), select "ASP.NET Core 6.0"
as the target framework, and click "Create".
- Add Middleware Folder and Class:
- Right-click on the project, select "Add"
> "New Folder", and name it "Middlewares".
- Right-click on the "Middlewares" folder,
select "Add" > "Class", and name it
"RequestLoggingMiddleware.cs".
3.
Implementing the Middleware
- Open RequestLoggingMiddleware.cs:
- Add the following code to implement the middleware
class:
csharp
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using System.Diagnostics;
using System.IO;
using System.Threading.Tasks;
namespace
CustomMiddlewareExample.Middlewares
{
public class RequestLoggingMiddleware
{
private readonly RequestDelegate _next;
private readonly
ILogger<RequestLoggingMiddleware> _logger;
public
RequestLoggingMiddleware(RequestDelegate next,
ILogger<RequestLoggingMiddleware> logger)
{
_next = next;
_logger = logger;
}
public async Task Invoke(HttpContext
context)
{
var watch = Stopwatch.StartNew();
var originalBodyStream =
context.Response.Body;
using (var responseBody = new
MemoryStream())
{
context.Response.Body =
responseBody;
await _next(context);
watch.Stop();
context.Response.Body =
originalBodyStream;
_logger.LogInformation($"Request: {context.Request.Method}
{context.Request.Path} - Body: {await
FormatRequestBody(context.Request)}");
_logger.LogInformation($"Response: {context.Response.StatusCode} -
Body: {await FormatResponseBody(responseBody)}");
_logger.LogInformation($"Duration: {watch.ElapsedMilliseconds}
ms");
await
responseBody.CopyToAsync(originalBodyStream);
}
}
private async Task<string>
FormatRequestBody(HttpRequest request)
{
request.EnableBuffering();
var body = await new
StreamReader(request.Body).ReadToEndAsync();
request.Body.Position = 0;
return body;
}
private async Task<string>
FormatResponseBody(Stream responseBody)
{
responseBody.Seek(0,
SeekOrigin.Begin);
var body = await new
StreamReader(responseBody).ReadToEndAsync();
responseBody.Seek(0,
SeekOrigin.Begin);
return body;
}
}
public static class RequestLoggingMiddlewareExtensions
{
public static IApplicationBuilder
UseRequestLogging(this IApplicationBuilder builder)
{
return
builder.UseMiddleware<RequestLoggingMiddleware>();
}
}
}
4.
Registering the Middleware
- Open Startup.cs:
- Add the following code to the Configure method to register the middleware:
csharp
using
CustomMiddlewareExample.Middlewares;
public class Startup
{
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
// Register the custom middleware
app.UseRequestLogging();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name:
"default",
pattern:
"{controller=Home}/{action=Index}/{id?}");
});
}
}
5.
Testing the Middleware
- Run the Application:
- Start the application by pressing F5 or clicking the
"Run" button.
- Make HTTP Requests:
- Use a tool like Postman or your browser to make HTTP
requests to your application endpoints.
- Check Logs:
- Check the logs in the console or log file to see the
logged requests and responses.
Detailed
Explanation and Benefits
- RequestDelegate:
Represents a function that can process an HTTP request.
- ILogger:
Used for logging information, which can help in debugging and monitoring.
- Stopwatch:
Measures the time taken to process the request.
- MemoryStream:
Used to temporarily store the response body.
- FormatRequestBody:
Reads and returns the request body as a string.
- FormatResponseBody:
Reads and returns the response body as a string.
Conclusion
Middleware is an essential part of
ASP.NET Core applications, allowing you to process requests and responses in a
flexible and modular way. By creating custom middleware, you can add specific
functionalities like logging, authentication, and error handling to your
application pipeline. This tutorial demonstrates how to create, register, and
test custom middleware in an ASP.NET Core MVC application.
POST Answer of Questions and ASK to Doubt