<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>Coder Legion - Recent posts tagged aspnet8</title>
<link>https://coderlegion.com/tag/aspnet8</link>
<description>Powered by Question2Answer</description>
<item>
<title>How To Create Custom Middlewares in ASP.NET Core</title>
<link>https://coderlegion.com/276/how-to-create-custom-middlewares-in-asp-net-core</link>
<description>&lt;p&gt;ASP.NET Core&amp;#x27;s middleware architecture offers a powerful way to build and configure the HTTP request pipeline in your applications.
In this post, you&amp;#x27;ll explore what middleware is and how to create a custom middlewares in ASP.NET Core.&lt;/p&gt;
&lt;h2&gt;What is Middleware in ASP.NET Core?&lt;/h2&gt;
&lt;p&gt;Middleware in ASP.NET Core is a software component that is a part of application pipeline that handles requests and responses.
In ASP.NET Core there are multiple middlewares that are combined in a chain with each other.&lt;/p&gt;
&lt;p&gt;Each middleware component in the pipeline is responsible for invoking the next component in the sequence.
Any middleware can stop other middlewares from execution by short-circuiting the chain if necessary.
Middlewares in ASP.NET Core is a classic implementation of &lt;strong&gt;chain of responsibility design pattern&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;ASP.NET Core has a lot of built-in middlewares and many provided by Nuget packages.
The &lt;strong&gt;order&lt;/strong&gt; in which middlewares are added to the application pipeline is &lt;strong&gt;critical&lt;/strong&gt;.
It defines how the incoming HTTP requests travel through the pipeline and in what sequence the responses are sent back.&lt;/p&gt;
&lt;p&gt;Middlewares are executed in the order they are added to the pipeline in the WebApplication object.
If you want to learn more about common middlewares and their correct order - &lt;a class=&quot;text-lg font-semibold leading-8 text-indigo-600&quot; href=&quot;https://antondevtips.com/blog/getting-started-with-middlewares-in-aspnet-core&quot; target=&quot;_blank&quot; rel=&quot;nofollow&quot;&gt;read my blog post&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;How To Create Custom Middleware in ASP.NET Core&lt;/h2&gt;
&lt;p&gt;You can create a custom middleware in the following ways:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;provide a delegate for &lt;code&gt;Use&lt;/code&gt; method in &lt;code&gt;WebApplication&lt;/code&gt; class&lt;/li&gt;
&lt;li&gt;create a Middleware class by convention&lt;/li&gt;
&lt;li&gt;create a Middleware class by inheriting from &lt;code&gt;IMiddleware&lt;/code&gt; interface&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;With a Use Method in WebApplication Class&lt;/h3&gt;
&lt;p&gt;You can call a &lt;code&gt;Use&lt;/code&gt; method on the &lt;code&gt;WebApplication&lt;/code&gt; class to create a middleware:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
    var builder = WebApplication.CreateBuilder(args);
    
    builder.Logging.AddConsole();
    
    var app = builder.Build();
    
    app.Use(async (context, next) =&amp;gt;
    {
        Console.WriteLine(&quot;Request is starting...&quot;);
    
        await next();
    
        Console.WriteLine(&quot;Request has finished&quot;);
    });
    
    app.MapGet(&quot;/api/books&quot;, () =&amp;gt;
    {
        var books = SeedService.GetBooks(10);
        return Results.Ok(books);
    });
    
    await app.RunAsync();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this example when calling a &lt;code&gt;/api/books&lt;/code&gt; endpoint, the middleware declared in the &lt;code&gt;Use&lt;/code&gt; method is called first.
&lt;code&gt;await next.Invoke()&lt;/code&gt; calls the books endpoint itself, but before and after we have a message logged to console:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
    Request is starting...
    Request has finished
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Middlewares are executed in the order they are added to the pipeline in the WebApplication object.
Each middleware can perform operations before and after the next middleware:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Before:&lt;/strong&gt; executing operations before calling the next middleware can include tasks like logging, authentication, validation, etc.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;After:&lt;/strong&gt; operations after calling the next middleware can include tasks like response modification or error handling.&lt;/p&gt;
&lt;p&gt;The real power of middlewares is that you can chain them freely in any order you want.
To stop the request from executing and short-cut the middleware chain (stop other middlewares from executing) - write a response directly into HttpContext instead of calling the &lt;code&gt;await next.Invoke()&lt;/code&gt; method:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
    await context.Response.WriteAsync(&quot;Some response here&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;With a Middleware Class by Convention&lt;/h3&gt;
&lt;p&gt;You can extract a middleware to a separate class that follows the specific convention:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
    public class LoggingMiddleware
    {
        private readonly RequestDelegate _next;
    
        public LoggingMiddleware(RequestDelegate next)
        {
            _next = next;
        }
    
        public async Task InvokeAsync(HttpContext context)
        {
            Console.WriteLine($&quot;Request: {context.Request.Method} {context.Request.Path}&quot;);
    
            await _next(context);
    
            Console.WriteLine($&quot;Response: {context.Response.StatusCode}&quot;);
        }
    }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To add this middleware to the pipeline, call the &lt;code&gt;UseMiddleware&lt;/code&gt; method on the &lt;code&gt;WebApplication&lt;/code&gt; class:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
    app.Use(async (context, next) =&amp;gt;
    {
        // Middleware from previous example
    });
    
    app.UseMiddleware();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As a result of executing this middleware the following will be logged to the console when executing an &lt;code&gt;/api/books&lt;/code&gt; endpoint:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
    Request is starting...
    Request: GET /api/books
    
    Response: 200
    Request has finished
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This approach is called by convention, because middleware class must follow these rules:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;middleware class should have a &lt;code&gt;InvokeAsync&lt;/code&gt; method with a required &lt;code&gt;HttpContext&lt;/code&gt; argument&lt;/li&gt;
&lt;li&gt;middleware class should inject a next &lt;code&gt;RequestDelegate&lt;/code&gt; in the constructor&lt;/li&gt;
&lt;li&gt;middleware class call the next &lt;code&gt;RequestDelegate&lt;/code&gt; delegate and pass it the &lt;code&gt;HttpContext&lt;/code&gt; argument&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;With a Middleware Class That Implements &lt;code&gt;IMiddleware&lt;/code&gt; Interface&lt;/h3&gt;
&lt;p&gt;The previous approach has its drawbacks: the developer needs to create a middleware class that follows all mentioned above rules, otherwise a middleware won&amp;#x27;t work.
But there is a safer way to create a middleware: implement the &lt;code&gt;IMiddleware&lt;/code&gt; interface:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
    public class ExecutionTimeMiddleware : IMiddleware
    {
        public async Task InvokeAsync(HttpContext context, RequestDelegate next)
        {
            var watch = Stopwatch.StartNew();
            
            await next(context);
            
            watch.Stop();
            
            Console.WriteLine($&quot;Request executed in {watch.ElapsedMilliseconds}ms&quot;);
        }
    }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This approach is much safer as the compiler tells how the middleware class should look like.&lt;/p&gt;
&lt;p&gt;For this approach you need to manually register &lt;code&gt;ExecutionTimeMiddleware&lt;/code&gt; in the DI container:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
    builder.Services.AddScoped();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To add this middleware to the pipeline, call the &lt;code&gt;UseMiddleware&lt;/code&gt; method on the &lt;code&gt;WebApplication&lt;/code&gt; class:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
    app.Use(async (context, next) =&amp;gt;
    {
        // Middleware from previous example
    });
    
    app.UseMiddleware();
    app.UseMiddleware();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As a result of executing this middleware the following will be logged to the console when executing an &lt;code&gt;/api/books&lt;/code&gt; endpoint:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
    Request is starting...
    Request: GET /api/books
    Request executed in 68ms
    
    Response: 200
    Request has finished
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Middlewares and Dependency Injection&lt;/h2&gt;
&lt;p&gt;Middlewares by convention have &lt;code&gt;Singleton&lt;/code&gt; lifetime by default and all dependencies injected in constructor must be &lt;strong&gt;singletons&lt;/strong&gt; too.
As we already know, middlewares run per each request, and you can inject &lt;strong&gt;scoped&lt;/strong&gt; dependencies in the &lt;code&gt;InvokeAsync&lt;/code&gt; method after &lt;code&gt;HttpContext&lt;/code&gt;.
Here we are injecting a &lt;code&gt;ILoggingService&lt;/code&gt; that is registered as &lt;strong&gt;scoped&lt;/strong&gt; service in DI:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
    builder.Services.AddScoped();

    public class LoggingMiddleware
    {
        private readonly RequestDelegate _next;
    
        public LoggingMiddleware(RequestDelegate next)
        {
            _next = next;
        }
    
        public async Task InvokeAsync(HttpContext context, ILoggingService loggingService)
        {
            loggingService.LogRequest(context.Request.Method, context.Request.Path);
    
            await _next(context);
    
            loggingService.LogResponse(context.Response.StatusCode);
        }
    }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This approach is suitable only for middleware classes created by &lt;strong&gt;convention&lt;/strong&gt;.
To inject scoped services into middleware classes that implement &lt;code&gt;IMiddleware&lt;/code&gt; interface, simply use the constructor:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
    public class ExecutionTimeMiddleware : IMiddleware
    {
        private readonly ILoggingService _loggingService;

        public ExecutionTimeMiddleware(ILoggingService loggingService)
        {
            _loggingService = loggingService;
        }

        public async Task InvokeAsync(HttpContext context, RequestDelegate next)
        {
            // ...
        }
    }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; when creating a middleware class that implements &lt;code&gt;IMiddleware&lt;/code&gt; interface - you are responsible for selecting an appropriate DI lifetime for it.
You can create &lt;code&gt;Singleton&lt;/code&gt;, &lt;code&gt;Scoped&lt;/code&gt; or &lt;code&gt;Transient&lt;/code&gt; middleware, select what suits the best in each use case.&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;You can create a custom middleware in the following ways:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;provide a delegate for &lt;code&gt;Use&lt;/code&gt; method in &lt;code&gt;WebApplication&lt;/code&gt; class&lt;/li&gt;
&lt;li&gt;create a Middleware class by convention&lt;/li&gt;
&lt;li&gt;create a Middleware class by inheriting from &lt;code&gt;IMiddleware&lt;/code&gt; interface&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;My preferred choice is to create a middleware by inheriting from the &lt;code&gt;IMiddleware&lt;/code&gt; interface.
This approach offers a safer, more convenient way to create middlewares and a straightforward dependency injection strategy through a constructor.
And it also gives a full control over the middleware lifetime.&lt;/p&gt;
</description>
<category>Coding</category>
<guid isPermaLink="true">https://coderlegion.com/276/how-to-create-custom-middlewares-in-asp-net-core</guid>
<pubDate>Mon, 13 May 2024 13:40:47 +0000</pubDate>
</item>
<item>
<title>Rate limiting middleware in ASP.NET Core using .NET 8.0</title>
<link>https://coderlegion.com/277/rate-limiting-middleware-in-asp-net-core-using-net-8-0</link>
<description>&lt;p&gt;&lt;strong&gt;Rate limiting middleware&lt;/strong&gt; in ASP.NET Core is a concept commonly associated with an API, where it states (&lt;strong&gt;a rate limiter in a web API&lt;/strong&gt;) is a mechanism used to &lt;strong&gt;control&lt;/strong&gt; the number of requests that a client can make to an API within a certain time frame. It helps prevent API misuse or abuse by limiting the number of requests from a particular client or IP address, ensuring &lt;strong&gt;fair usage&lt;/strong&gt;, and &lt;strong&gt;protecting server resources&lt;/strong&gt; from being overwhelmed.&lt;/p&gt;
&lt;div class=&quot;div-blue&quot;&gt;
&lt;span class=&quot;alert-header&quot;&gt;Note:&lt;/span&gt;
&lt;span class=&quot;alert-body&quot;&gt;This concept has been integrated as a middleware with .NET 7 and later.&lt;/span&gt;
&lt;/div&gt;
&lt;hr&gt;
&lt;p&gt;In the .Net environment, we have 4 types of algorithms that we can use in this regard:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1) Fixed window limiter&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2) Sliding window limiter&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3) Token bucket limiter&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;4) Concurrency limiter&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;We will explain each of them in a simplified manner.&lt;/p&gt;
&lt;h2 id=&quot;1-fixed-window-limiter&quot;&gt;1) Fixed window limiter&lt;/h2&gt;
&lt;p&gt;Fixed window limiter stipulates that there is a time limit for the window in which a number of requests can be executed, meaning that the number of requests must not exceed the permitted number in a specific, pre-determined time.&lt;/p&gt;
&lt;p&gt;For example, 6 seconds for the window. You can execute a number of requests, for example 1 requests. If it exceeds this number, it must go to the waiting queue, for which we can also prepare an expected space, for example, 1 waiting requests. If the number of requests exceeds this number, an error message will be returned to the user because he has exceeded his permissible limit of requests, in most cases 429 in the case of an answer.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;builder.Services.AddRateLimiter(option =&amp;gt;
{
    option.AddFixedWindowLimiter(&quot;FixedWindowPolicy&quot;, opt =&amp;gt;
    {
        opt.PermitLimit = 1; // items allow processing
        opt.Window = TimeSpan.FromSeconds(6); // time need to process PermitLimit items's
        opt.QueueLimit = 1; // items allow be in Queue waiting

        opt.QueueProcessingOrder = System.Threading.RateLimiting.QueueProcessingOrder.OldestFirst;//Order the items in Queue Waiting
    }).RejectionStatusCode = 429; // This means that this request is not allowed at this time due to the large number of requests received now
});
&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h2 id=&quot;2-sliding-window-limiter&quot;&gt;2) Sliding Window Limiter&lt;/h2&gt;
&lt;p&gt;The sliding window limiter is similar to the fixed window limiter but offers more flexibility. It processes old requests while tracking ongoing ones, allowing it to handle new requests based on the status of previously submitted but incomplete requests.&lt;/p&gt;
&lt;p&gt;For example, I have a window that lasts 6 seconds and receives 4 requests for this window. I can divide the window into three sliding windows (three segments per window). Here, this one window processes 4 requests. It executes what it can from it and passes it to the second window. And so, it goes for the second window as well. It executes and passes it to the window. The first is that if the sliding window has space to receive new requests, it pops up again in order to receive new requests while taking into account old requests that have not been completed.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;builder.Services.AddRateLimiter(option =&amp;gt;
{
    option.AddSlidingWindowLimiter(&quot;SlidWindowPolicy&quot;, opt =&amp;gt;
    {
        opt.PermitLimit = 4; // items allow processing
        opt.Window = TimeSpan.FromSeconds(6); // time need to process PermitLimit items's
        opt.QueueLimit = 5; // items allow be in Queue waiting
        opt.QueueProcessingOrder = System.Threading.RateLimiting.QueueProcessingOrder.OldestFirst;//Order the items in Queue Waiting
        opt.SegmentsPerWindow = 3;
    }).RejectionStatusCode = 429; // This means that this request is not allowed at this time due to the large number of requests received now
});
&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h2 id=&quot;3-token-bucket-limiter&quot;&gt;3) Token Bucket Limiter&lt;/h2&gt;
&lt;p&gt;The token bucket limiter is a straightforward yet effective rate limiting technique. It uses a bucket to hold a set number of tokens, each representing permission to handle one request. When a request is made, a token is removed from the bucket. If the bucket is empty, the request is denied until more tokens become available.Tokens are replenished at a fixed rate over time, ensuring that the system can handle bursts of requests followed by idle periods.  &lt;/p&gt;
&lt;p&gt;For example, in a token bucket rate limiting algorithm, you might have a bucket that can hold up to 100 tokens. Each incoming request consumes one token, so the bucket's token count decreases with each request. To ensure that the system can handle bursts of requests, new tokens are added to the bucket at a specified interval (e.g., 3 tokens every 5 seconds), without exceeding the maximum bucket size of 100 tokens. This mechanism prevents request flooding while allowing occasional spikes in request rate.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;builder.Services.AddRateLimiter(option =&amp;gt;
{
    option.AddTokenBucketLimiter(&quot;TokenBucketPolicy&quot;, opt =&amp;gt;
    {
        opt.TokenLimit = 100; // Maximum number of tokens in the bucket
        opt.QueueLimit = 10; // Number of requests that can wait in the queue
        opt.QueueProcessingOrder = System.Threading.RateLimiting.QueueProcessingOrder.OldestFirst; // Order of processing queued requests
        opt.ReplenishmentPeriod = TimeSpan.FromSeconds(5); // Time period for adding new tokens
        opt.TokensPerPeriod = 3; // Number of tokens added each period
    }).RejectionStatusCode = 429; // Status code returned when rate limit is exceeded
});
&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h2 id=&quot;4-concurrency-limiter&quot;&gt;4) Concurrency limiter&lt;/h2&gt;
&lt;p&gt;Concurrency limiter limits the number of concurrent requests. Each request reduces the concurrency limit by one. When the order is completed, the limit is increased by one.&lt;/p&gt;
&lt;p&gt;For example, we have a synchronization limit of 1 operation. Here, only one will be responsible for performing 1 simultaneous operation, meaning it must not exceed this limit.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;builder.Services.AddRateLimiter(option =&amp;gt;
{
    option.AddConcurrencyLimiter(&quot;ConcurrencyPolicy&quot;, opt =&amp;gt;
    {
        opt.PermitLimit = 1; // Maximum number of concurrent requests allowed
        opt.QueueLimit = 10; // Number of requests that can wait in the queue
        opt.QueueProcessingOrder = System.Threading.RateLimiting.QueueProcessingOrder.OldestFirst; // Order of processing queued requests
    }).RejectionStatusCode = 429; // Status code returned when rate limit is exceeded
});
&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;In the end, to connect it to the endpoint you can use two methods:&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id=&quot;by-using-controller-endpoint-&quot;&gt;&lt;strong&gt;By using Controller endpoint:&lt;/strong&gt;&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;[HttpGet(&quot;GetConcurrency&quot;)]
[EnableRateLimiting(&quot;ConcurrencyWindowPolicy&quot;)]

public IActionResult GetConcurrency()
{
    return Ok(&quot;Concurrency&quot;);
}  

[HttpGet(&quot;GetFixed&quot;)]
[EnableRateLimiting(&quot;FixedWindowPolicy&quot;)]

public IActionResult GetFixed()
{
    return Ok(&quot;Fixed&quot;);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[DisableRateLimiting]
public ActionResult NoLimit()
{
    return Ok(&quot;NoLimit&quot;);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;strong&gt;EnableRateLimiting&lt;/strong&gt; attribute is used to apply a specified rate limiting policy to an action method. When this attribute is applied to a method, the rate limiting rules defined by the specified policy are enforced for that method. This means that any incoming requests to the action will be subject to the constraints of the policy, such as the maximum number of requests allowed in a given time period.&lt;/p&gt;
&lt;h3 id=&quot;by-using-minimal-endpoint-&quot;&gt;&lt;strong&gt;By using Minimal endpoint:&lt;/strong&gt;&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt; app.MapGet(&quot;/&quot;, () =&amp;gt; Results.Ok(&quot;fixed&quot;)).RequireRateLimiting(&quot;FixedWindowPolicy&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;strong&gt;RequireRateLimiting&lt;/strong&gt; method is similar to &lt;em&gt;EnableRateLimiting&lt;/em&gt;, but it is used in the context of endpoint routing. It attaches a rate limiting policy directly to an endpoint defined in the routing configuration. When a request matches the route, the specified rate limiting policy is applied.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;importance-of-rate-limiting-for-api-providers&quot;&gt;Importance of Rate Limiting for API Providers&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;1. Maintaining Service Reliability&lt;/strong&gt;&lt;br&gt;
Rate limiting helps ensure that an API remains responsive and available, even under heavy load. &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2. Preventing Abuse&lt;/strong&gt;&lt;br&gt;
APIs are often targets for malicious activities, such as denial-of-service (DoS) attacks, scraping, and other forms of abuse. Rate limiting acts as a safeguard against these threats by limiting the rate at which requests can be made, thereby reducing the impact of automated attacks and ensuring that legitimate users can access the service.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3. Ensuring Fair Resource Allocation&lt;/strong&gt;&lt;br&gt;
Rate limiting ensures that resources are distributed fairly among all users. Without rate limiting, a few users might consume a disproportionate amount of server resources, leading to poor performance or service degradation for others. &lt;/p&gt;
&lt;h2 id=&quot;in-the-end&quot;&gt;&lt;strong&gt;In the end&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;In the end, these rate limiting algorithms can be fine-tuned using additional parameters, such as client IP addresses or user authorization levels, to impose more detailed limits tailored to specific user profiles. By implementing rate limiting with precise parameters, API providers can ensure optimal performance, fair resource allocation, and protection against abuse across all user interactions with the API.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Fine-Tuning Rate Limiting&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Client IP Addresses:&lt;/strong&gt; Apply rate limits based on the IP address of the client, allowing more granular control over request rates from different sources.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;User Authorization Levels:&lt;/strong&gt; Differentiate rate limits based on user roles or authorization levels, providing higher limits for premium users and lower limits for regular users.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Custom Rules:&lt;/strong&gt; Create custom rate limiting rules to accommodate specific application needs, such as limiting requests based on geographic regions or specific API endpoints.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;More resources &lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://www.youtube.com/watch?v=bOfOo3Zsfx0&quot;&gt;https://www.youtube.com/watch?v=bOfOo3Zsfx0&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://learn.microsoft.com/en-us/aspnet/core/performance/rate-limit?view=aspnetcore-8.0&quot;&gt;https://learn.microsoft.com/en-us/aspnet/core/performance/rate-limit?view=aspnetcore-8.0&lt;/a&gt;&lt;/p&gt;
</description>
<category>ASP.NET</category>
<guid isPermaLink="true">https://coderlegion.com/277/rate-limiting-middleware-in-asp-net-core-using-net-8-0</guid>
<pubDate>Sat, 11 May 2024 20:54:38 +0000</pubDate>
</item>
<item>
<title>Null Reference Exceptions in C# - Fixed</title>
<link>https://coderlegion.com/98/null-reference-exceptions-in-c-fixed</link>
<description>&lt;p&gt;Sometimes, during our projects, we might get a Null Reference Exception coming from a deep and forgotten part of our code.&lt;/p&gt;
&lt;p&gt;In this article, we will understand why it happens, and explore a few ways to solve it.&lt;/p&gt;
&lt;p&gt;Whenever you try to access an object or variable, which is not properly instantiated or initialized, you might get a Null Reference Exception.&lt;/p&gt;
&lt;p&gt;Let's look at the example below. We have a class called  &lt;code&gt;People&lt;/code&gt;, with a property called &lt;code&gt;Name&lt;/code&gt;, which type is a class. Although the property &lt;code&gt;FullName&lt;/code&gt; treats the error of getting its value before its being assigned, returning a default empty string, we don't have the same for &lt;code&gt;Name&lt;/code&gt; property within &lt;code&gt;People&lt;/code&gt; class.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;try
{

    var joel = new People();
    var joelsName = joel.Name.FullName; //throws an Exception
    
}
catch (System.Exception exp)
{
    System.Console.WriteLine(exp);
}

class People {
public Name Name { get; set; }
}
class Name { 
    public string FullName { get; set; } = String.Empty;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Running the code above results in the following:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;constructor. Consider declaring the property as nullable. [..\dotnetlabs\NullReference\NullReference.csproj]
System.NullReferenceException: Object reference not set to an instance of an object.
   at Program.&amp;lt;Main&amp;gt;$(String[] args) in
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;Note: I removed the path information once that is private. In your&lt;br&gt;
case the location of your program would be shown instead.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Now that we understand why this error happens, it's time to solve it. I listed three solutions you can take in your code to avoid getting this Exception.&lt;/p&gt;
&lt;h3 id=&quot;solution-1-declaring-variables-as-being-nullable&quot;&gt;Solution 1:  Declaring variables as being nullable&lt;/h3&gt;
&lt;p&gt;If you intend to use null in your logic, then you must declare the variables as nullable by adding a question mark at the end of the name.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;try
{
    var joel = new People();

    var joelsName = joel.Name?.FullName; // we don't get NullReference Exception any more
    
}
catch (System.Exception exp)
{
    
    System.Console.WriteLine(exp);
}

class People {
public Name? Name { get; set; }
}
class Name { 
    public string FullName { get; set; } = String.Empty;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Observe that I put the question mark in the property declaration and also when I invoke it to access the &lt;code&gt;FullName&lt;/code&gt; property.&lt;br&gt;
The code above doesn't throw an Exception anymore,  once the program understands now that a null value is expected from &lt;code&gt;Name&lt;/code&gt; property.&lt;/p&gt;
&lt;h3 id=&quot;solution-2-treating-the-getter&quot;&gt;Solution 2: Treating the getter&lt;/h3&gt;
&lt;p&gt;Another option is to intercept when the program tries to read the Name property, so whenever the program tries to read the property it checks if it is null first, if so then returns a new instance of the object:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;try
{
    var joel = new People();

    var joelsName = joel.Name.FullName; // we don't get NullReference Exception any more

}
catch (System.Exception exp)
{

    System.Console.WriteLine(exp);
}

class People
{
    private Name? _name;

    public Name Name
    {
        get
        {
            if (_name is null) 
            { 
                return new Name(); 
            }

            return _name;
        }
        set
        {
            _name = value;
        }
    }
}
class Name
{
    public string FullName { get; set; } = String.Empty;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;solution-3-using-constructors&quot;&gt;Solution 3: Using constructors&lt;/h3&gt;
&lt;p&gt;A third option is to guarantee the properties and variable values using constructors. Whenever a constructor is defined, it forces you to instantiate the object. You should use the constructor logic to make sure none of your variables and properties are null.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;try
{
    var joel = new People(&quot;Joel Smith&quot;);

    var joelsName = joel.Name.FullName;

    Console.WriteLine(joelsName);

}
catch (System.Exception exp)
{

    System.Console.WriteLine(exp);
}

class People
{
    public Name Name { get; set; }

    public People(string name)
    {
        Name = new Name(name);
    }
}
class Name
{
    public string FullName { get; set; } = String.Empty;
    public Name(string name)
    {
        FullName = name;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;In the majority of cases, you should avoid working with null values, as they might be a bad idea if not handled properly. However, there are a few cases in which we can use nulls to represent badly parsed data or a no value when querying some database. If so, you must treat them correctly to avoid your program breaking unexpectedly.&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/98/null-reference-exceptions-in-c-fixed</guid>
<pubDate>Sat, 10 Feb 2024 03:09:53 +0000</pubDate>
</item>
</channel>
</rss>