<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Dotnet on Ravindra Devrani</title><link>https://ravindradevrani.com/tags/dotnet/</link><description>Recent content in Dotnet on Ravindra Devrani</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Tue, 10 Feb 2026 16:05:18 +0530</lastBuildDate><atom:link href="https://ravindradevrani.com/tags/dotnet/index.xml" rel="self" type="application/rss+xml"/><item><title>Dotnet Core Identity With .NET CLI</title><link>https://ravindradevrani.com/posts/dotnet-core-identity-with-dotnet-cli/</link><pubDate>Tue, 10 Feb 2026 16:05:18 +0530</pubDate><guid>https://ravindradevrani.com/posts/dotnet-core-identity-with-dotnet-cli/</guid><description>&lt;p>&lt;code>Aspnet core identity&lt;/code> provides an UI to registration, login, manage users, password, external authentication (google, twitter, facebook etc). In simple words, We can say it is an authentication and authorization feature in just few lines of commands and code. It is a nice feature, if you don&amp;rsquo;t want to use other managed authentication providers like Azure Entra Id / Okta Auth0 etc.&lt;/p>
&lt;p>Visual studio provides an UI way to enable identity. Which is very straightforward, but using CLI can be a little bit tricky. It is not always the case you are using visual studio (specially if you are using mac or linux). I use linux also. That is the whole reason to write this article.&lt;/p></description></item><item><title>Dotnet Core API Crud With Mysql and EF Core</title><link>https://ravindradevrani.com/posts/dotnet-core-api-crud-with-mysql-efcore/</link><pubDate>Mon, 29 Dec 2025 11:19:51 +0530</pubDate><guid>https://ravindradevrani.com/posts/dotnet-core-api-crud-with-mysql-efcore/</guid><description>&lt;p>In this tutorial, we are going to make dotnet core web api application and perform all the CRUD (create, read, update and delete). I have tried to keep it simple and avoided any complexities like repository pattern.&lt;/p>
&lt;p>&lt;a href="https://github.com/rd003/DotnetPracticeDemos/tree/master/BlogDemos/MySqlEfCore">💻Source code&lt;/a>&lt;/p>
&lt;h2 id="tech-and-tools-used">Tech and tools used&lt;/h2>
&lt;ul>
&lt;li>Dotnet 10&lt;/li>
&lt;li>MySql 8+ (in docker container. Click &lt;a href="https://ravindradevrani.com/posts/mysql-in-docker/">here&lt;/a>, if you want to create a MySql container in docker)&lt;/li>
&lt;li>Entity Framework Core (ORM)&lt;/li>
&lt;li>.NET CLI and VS Code (alternate Visual Studio 2025)&lt;/li>
&lt;/ul>
&lt;h2 id="creating-a-project">Creating a project&lt;/h2>
&lt;p>Execute these commands in a sequence.&lt;/p></description></item><item><title>Dotnet Core API Crud With Mysql and Dapper</title><link>https://ravindradevrani.com/posts/dotnet-crud-with-mysql-and-dapper/</link><pubDate>Thu, 25 Dec 2025 11:19:51 +0530</pubDate><guid>https://ravindradevrani.com/posts/dotnet-crud-with-mysql-and-dapper/</guid><description>&lt;p>In this tutorial, we are going to make dotnet core web api application and perform all the CRUD (create, read, update and delete). I have tried to keep it simple and avoided any complexities like repository pattern.&lt;/p>
&lt;p>&lt;a href="https://github.com/rd003/DotnetPracticeDemos/tree/master/BlogDemos/DapperMysql">💻Source code&lt;/a>&lt;/p>
&lt;h2 id="tech-and-tools-used">Tech and tools used&lt;/h2>
&lt;ul>
&lt;li>Dotnet 10&lt;/li>
&lt;li>MySql 8+ (in docker container. Click &lt;a href="https://ravindradevrani.com/posts/mysql-in-docker/">here&lt;/a>, if you want to create a MySql container in docker)&lt;/li>
&lt;li>Dapper (ORM)&lt;/li>
&lt;li>.NET CLI and VS Code (alternate Visual Studio 2025)&lt;/li>
&lt;/ul>
&lt;h2 id="create-database">Create database&lt;/h2>
&lt;p>Let&amp;rsquo;s start with creating a database and a table. You need to execute this script.&lt;/p></description></item><item><title>LeftJoin and RightJoin in Ef Core 10</title><link>https://ravindradevrani.com/posts/left-join-ef-core-10/</link><pubDate>Tue, 16 Dec 2025 09:40:05 +0530</pubDate><guid>https://ravindradevrani.com/posts/left-join-ef-core-10/</guid><description>&lt;p>Previously there was no simple solution for left or right join. We had to use &lt;code>DefaultIfEmpty&lt;/code> or &lt;code>GroupJoin&lt;/code> and &lt;code>SelectMany&lt;/code>.&lt;/p>
&lt;p>With &lt;code>DefaultIfEmpty()&lt;/code>:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-cs" data-lang="cs">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">var&lt;/span> customerOrders = &lt;span style="color:#66d9ef">await&lt;/span> (
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">from&lt;/span> c &lt;span style="color:#66d9ef">in&lt;/span> ctx.Customers
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">join&lt;/span> o &lt;span style="color:#66d9ef">in&lt;/span> ctx.Orders &lt;span style="color:#66d9ef">on&lt;/span> c.CustomerId &lt;span style="color:#66d9ef">equals&lt;/span> o.CustomerId &lt;span style="color:#66d9ef">into&lt;/span> orders
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">from&lt;/span> o &lt;span style="color:#66d9ef">in&lt;/span> orders.DefaultIfEmpty()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">select&lt;/span> &lt;span style="color:#66d9ef">new&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> c.CustomerId,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> c.CustomerName,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> OrderId = o == &lt;span style="color:#66d9ef">null&lt;/span> ? &lt;span style="color:#ae81ff">0&lt;/span> : o.OrderId
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>).ToListAsync();
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>I have used the way described above in most of my career. It was really hard to remember that syntax and I always struggled with that.&lt;/p></description></item><item><title>Cartesian Explosion and Split Query in Entity Framework Core</title><link>https://ravindradevrani.com/posts/cartesian-explosion-and-split-query-in-entity-framework-core/</link><pubDate>Sun, 07 Dec 2025 20:03:37 +0530</pubDate><guid>https://ravindradevrani.com/posts/cartesian-explosion-and-split-query-in-entity-framework-core/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>In this tutorial, we will understand what cartesian explosion is and how to solve that problem. Let&amp;rsquo;s look at this query:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-cs" data-lang="cs">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">var&lt;/span> people = &lt;span style="color:#66d9ef">await&lt;/span> ctx.People
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> .Include(p =&amp;gt; p.Emails)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> .Include(p =&amp;gt; p.Addresses)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> .ToListAsync();
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>It translates to:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-sql" data-lang="sql">&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">SELECT&lt;/span> &lt;span style="color:#e6db74">&amp;#34;p&amp;#34;&lt;/span>.&lt;span style="color:#e6db74">&amp;#34;Id&amp;#34;&lt;/span>, &lt;span style="color:#e6db74">&amp;#34;p&amp;#34;&lt;/span>.&lt;span style="color:#e6db74">&amp;#34;FirstName&amp;#34;&lt;/span>, &lt;span style="color:#e6db74">&amp;#34;p&amp;#34;&lt;/span>.&lt;span style="color:#e6db74">&amp;#34;LastName&amp;#34;&lt;/span>, &lt;span style="color:#e6db74">&amp;#34;e&amp;#34;&lt;/span>.&lt;span style="color:#e6db74">&amp;#34;Id&amp;#34;&lt;/span>, &lt;span style="color:#e6db74">&amp;#34;e&amp;#34;&lt;/span>.&lt;span style="color:#e6db74">&amp;#34;PersonEmail&amp;#34;&lt;/span>, &lt;span style="color:#e6db74">&amp;#34;e&amp;#34;&lt;/span>.&lt;span style="color:#e6db74">&amp;#34;PersonId&amp;#34;&lt;/span>, &lt;span style="color:#e6db74">&amp;#34;a&amp;#34;&lt;/span>.&lt;span style="color:#e6db74">&amp;#34;Id&amp;#34;&lt;/span>, &lt;span style="color:#e6db74">&amp;#34;a&amp;#34;&lt;/span>.&lt;span style="color:#e6db74">&amp;#34;PersonAddress&amp;#34;&lt;/span>, &lt;span style="color:#e6db74">&amp;#34;a&amp;#34;&lt;/span>.&lt;span style="color:#e6db74">&amp;#34;PersonId&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">FROM&lt;/span> &lt;span style="color:#e6db74">&amp;#34;People&amp;#34;&lt;/span> &lt;span style="color:#66d9ef">AS&lt;/span> &lt;span style="color:#e6db74">&amp;#34;p&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">LEFT&lt;/span> &lt;span style="color:#66d9ef">JOIN&lt;/span> &lt;span style="color:#e6db74">&amp;#34;Emails&amp;#34;&lt;/span> &lt;span style="color:#66d9ef">AS&lt;/span> &lt;span style="color:#e6db74">&amp;#34;e&amp;#34;&lt;/span> &lt;span style="color:#66d9ef">ON&lt;/span> &lt;span style="color:#e6db74">&amp;#34;p&amp;#34;&lt;/span>.&lt;span style="color:#e6db74">&amp;#34;Id&amp;#34;&lt;/span> &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#e6db74">&amp;#34;e&amp;#34;&lt;/span>.&lt;span style="color:#e6db74">&amp;#34;PersonId&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">LEFT&lt;/span> &lt;span style="color:#66d9ef">JOIN&lt;/span> &lt;span style="color:#e6db74">&amp;#34;Addresses&amp;#34;&lt;/span> &lt;span style="color:#66d9ef">AS&lt;/span> &lt;span style="color:#e6db74">&amp;#34;a&amp;#34;&lt;/span> &lt;span style="color:#66d9ef">ON&lt;/span> &lt;span style="color:#e6db74">&amp;#34;p&amp;#34;&lt;/span>.&lt;span style="color:#e6db74">&amp;#34;Id&amp;#34;&lt;/span> &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#e6db74">&amp;#34;a&amp;#34;&lt;/span>.&lt;span style="color:#e6db74">&amp;#34;PersonId&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">ORDER&lt;/span> &lt;span style="color:#66d9ef">BY&lt;/span> &lt;span style="color:#e6db74">&amp;#34;p&amp;#34;&lt;/span>.&lt;span style="color:#e6db74">&amp;#34;Id&amp;#34;&lt;/span>, &lt;span style="color:#e6db74">&amp;#34;e&amp;#34;&lt;/span>.&lt;span style="color:#e6db74">&amp;#34;Id&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;ul>
&lt;li>&lt;code>Person&lt;/code> joins with &lt;code>Email&lt;/code> and &lt;code>Address&lt;/code>. Both joins are at the same level.&lt;/li>
&lt;li>A person can have multiple emails and adressess.&lt;/li>
&lt;/ul>
&lt;p>Let&amp;rsquo;s say a person with id = 1 have 10 emails and 10 addresses. The query returns 1x10x10 = 100 rows for 1 person. It is just for one person, how much they can be for 100 people. This problem is known as &lt;code>cartesian explosion&lt;/code>&lt;/p></description></item><item><title>Lazy Loading and N+1 Query Problem in Entity framework Core</title><link>https://ravindradevrani.com/posts/lazy-loading-and-n-plus-one-query-problem-in-ef-core/</link><pubDate>Thu, 27 Nov 2025 15:34:26 +0530</pubDate><guid>https://ravindradevrani.com/posts/lazy-loading-and-n-plus-one-query-problem-in-ef-core/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>&lt;a href="https://github.com/rd003/DotnetPracticeDemos/tree/master/LazyLoadingExample">💻Source code&lt;/a>&lt;/p>
&lt;h2 id="lazy-loading">Lazy loading&lt;/h2>
&lt;p>You load related entities on demand rather loading at once. This approach is usually useful when you want to load related entities on a certain condition (otherwise always use eager loading).&lt;/p>
&lt;p>To enable lazy loading, you need to install this package: &lt;code>Microsoft.EntityFrameworkCore.Proxies&lt;/code>&lt;/p>
&lt;p>And do following changes in &lt;code>Program.cs&lt;/code>&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-cs" data-lang="cs">&lt;span style="display:flex;">&lt;span>builder.Services.AddDbContext&amp;lt;AppDbContext&amp;gt;(o=&amp;gt;o.UseLazyLoadingProxies()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>.UseSqlite(&lt;span style="color:#e6db74">&amp;#34;Data Source = mydb.db&amp;#34;&lt;/span>));
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Look at the example below:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-cs" data-lang="cs">&lt;span style="display:flex;">&lt;span>app.MapGet(&lt;span style="color:#e6db74">&amp;#34;/&amp;#34;&lt;/span>, &lt;span style="color:#66d9ef">async&lt;/span> (AppDbContext context) =&amp;gt; {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">foreach&lt;/span> (&lt;span style="color:#66d9ef">var&lt;/span> genre &lt;span style="color:#66d9ef">in&lt;/span> &lt;span style="color:#66d9ef">await&lt;/span> context.Genres.ToListAsync()) 
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">foreach&lt;/span> (&lt;span style="color:#66d9ef">var&lt;/span> book &lt;span style="color:#66d9ef">in&lt;/span> genre.Books)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Console.WriteLine(&lt;span style="color:#e6db74">$&amp;#34;===&amp;gt; genre: {genre.Name}, Book: {book.Title}, Price : {book.Author}&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> Results.Ok(&lt;span style="color:#e6db74">&amp;#34;Ok&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>});
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>We are not loading &lt;code>books&lt;/code> with &lt;code>genres&lt;/code> at once. Rather we are loading books for each genres. Let&amp;rsquo;s take a look at &lt;code>logs of console&lt;/code>.&lt;/p></description></item><item><title>Content Negotiation in Dotnet Core Webapi</title><link>https://ravindradevrani.com/posts/content-negotiation-in-dotnetcore-webapi/</link><pubDate>Sat, 22 Nov 2025 16:23:29 +0530</pubDate><guid>https://ravindradevrani.com/posts/content-negotiation-in-dotnetcore-webapi/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>As defined in &lt;a href="https://datatracker.ietf.org/doc/html/rfc2616#section-12">rfc2616&lt;/a> - &lt;strong>&amp;ldquo;Content nagotiation is the process of selecting the best representation for a given response when there are multiple representations available.&amp;rdquo;&lt;/strong>&lt;/p>
&lt;p>Clients passes the header &lt;code>Accept&lt;/code> with values like &lt;code>application/json&lt;/code>,&lt;code>application/xml&lt;/code> etc and tells this format is acceptable. Then server gives the response according to that.&lt;/p>
&lt;p>In simpler terms, if your API supports xml, json and csv media type, then let clients decide which kind of media type they need as a response.&lt;/p></description></item><item><title>Containerizing Dotnet App With PostgreSql Using Docker Compose</title><link>https://ravindradevrani.com/posts/containerizing-dotnet-app-with-postgresql-using-docker-compose/</link><pubDate>Fri, 21 Nov 2025 13:33:14 +0530</pubDate><guid>https://ravindradevrani.com/posts/containerizing-dotnet-app-with-postgresql-using-docker-compose/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>In this tutorial, we are going to &lt;strong>containerize the .NET Web API application with docker and postgres&lt;/strong>. I am assuming you are familiar with docker. At least, you should have some understandings of how docker works. However, I have covered all the steps needed to create a docker container for your application, but I am not going to cover the &lt;a href="https://en.wikipedia.org/wiki/Docker_%28software%29">theoretical concepts&lt;/a> of docker.&lt;/p>
&lt;p>&lt;strong>📢Last updated : 21-Nov-2025&lt;/strong>&lt;/p></description></item><item><title>Containerizing Dotnet App With Sql Server Using Docker Compose</title><link>https://ravindradevrani.com/posts/containerizing-dotnet-app-with-sql-server-using-docker-compose/</link><pubDate>Thu, 20 Nov 2025 13:57:05 +0530</pubDate><guid>https://ravindradevrani.com/posts/containerizing-dotnet-app-with-sql-server-using-docker-compose/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>In this tutorial, we are going to containerize the .NET Web API application with docker. I am assuming you are familiar with docker. At least, you should have some understandings of how docker works. However, I have covered all the steps needed to create a docker container for your application, but I am not going to cover the &lt;a href="https://en.wikipedia.org/wiki/Docker_%28software%29">theoretical concepts&lt;/a> of docker.&lt;/p>
&lt;h2 id="last-updated-on">Last updated on:&lt;/h2>
&lt;ul>
&lt;li>20-November-2025&lt;/li>
&lt;/ul>
&lt;h3 id="tools-needed">🔨Tools needed&lt;/h3>
&lt;ul>
&lt;li>Visual Studio Code (Free)&lt;/li>
&lt;li>.Net 10.0 SDK (Free)&lt;/li>
&lt;li>Docker desktop (Free)&lt;/li>
&lt;/ul>
&lt;h3 id="tech-used">🧑‍💻Tech used&lt;/h3>
&lt;ul>
&lt;li>.Net 10.0 Web APIs (controller APIs)&lt;/li>
&lt;li>Ms SQL Server 2025 (within a container)&lt;/li>
&lt;li>Docker compose&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>🍵Note:&lt;/strong> I am using windows 11 operating system. However, I also have tested it in the Linux mint xia and it is working fine.&lt;/p></description></item><item><title>Azure Key Vault With Dotnet</title><link>https://ravindradevrani.com/posts/azure-key-vault-with-dotnet/</link><pubDate>Mon, 22 Sep 2025 10:25:42 +0530</pubDate><guid>https://ravindradevrani.com/posts/azure-key-vault-with-dotnet/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>First of all, let&amp;rsquo;s see what are we going to achieve? Let&amp;rsquo;s say we have an dotnet 9 api application.&lt;/p>
&lt;p>Its &lt;code>appsettings.json&lt;/code> looks like:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-js" data-lang="js">&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#34;Color&amp;#34;&lt;/span>&lt;span style="color:#f92672">:&lt;/span> &lt;span style="color:#e6db74">&amp;#34;Color from appsettings&amp;#34;&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#34;Person&amp;#34;&lt;/span>&lt;span style="color:#f92672">:&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#34;Name&amp;#34;&lt;/span>&lt;span style="color:#f92672">:&lt;/span> &lt;span style="color:#e6db74">&amp;#34;Name from appsettings&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Let&amp;rsquo;s try to retrieve these values:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-cs" data-lang="cs">&lt;span style="display:flex;">&lt;span>app.MapGet(&lt;span style="color:#e6db74">&amp;#34;/&amp;#34;&lt;/span>, (IConfiguration config) =&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">string&lt;/span> color = config.GetSection(&lt;span style="color:#e6db74">&amp;#34;Color&amp;#34;&lt;/span>).Value ?? &lt;span style="color:#e6db74">&amp;#34;No color&amp;#34;&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">string&lt;/span> name = config.GetSection(&lt;span style="color:#e6db74">&amp;#34;Person:Name&amp;#34;&lt;/span>).Value ?? &lt;span style="color:#e6db74">&amp;#34;No name&amp;#34;&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> Results.Ok(&lt;span style="color:#66d9ef">new&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> color,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> name,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> message = &lt;span style="color:#e6db74">&amp;#34;Hello there...&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> });
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>});
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>If you visit this endpoint, you will see this output:&lt;/p></description></item><item><title>Azure App Configuration With Dotnet(C#)</title><link>https://ravindradevrani.com/posts/azure-app-configuration-with-dotnet-csharp/</link><pubDate>Sat, 20 Sep 2025 16:56:26 +0530</pubDate><guid>https://ravindradevrani.com/posts/azure-app-configuration-with-dotnet-csharp/</guid><description>&lt;!-- raw HTML omitted -->
&lt;ul>
&lt;li>Azure &lt;code>App Configuration&lt;/code> is a fully managed service, which provides you a way to store the configurations in a centralized store. You can store configurations of multiple apps in a single place.&lt;/li>
&lt;li>It is really helpful for cloud native application (eg. Microservices), which runs on multiple virtual machines and use multiple external services.&lt;/li>
&lt;li>It allows us to store Key-value pairs, manage feature flags, and organize configurations using labels and namespaces.&lt;/li>
&lt;li>The main benefit is, it supports &lt;a href="https://learn.microsoft.com/en-us/azure/azure-app-configuration/enable-dynamic-configuration-aspnet-core">dynamic refreshing&lt;/a>. Which means, you can change config values without restarting the app.&lt;/li>
&lt;li>You can also add reference of azure key vault secret here.&lt;/li>
&lt;/ul>
&lt;p>Let&amp;rsquo;s see these things in action.&lt;/p></description></item><item><title>Azure Blob Storage : CRUD With AspNetCore Mvc &amp; SQL Server</title><link>https://ravindradevrani.com/posts/blob-storage-with-dotnet-mvc/</link><pubDate>Mon, 08 Sep 2025 12:49:37 +0530</pubDate><guid>https://ravindradevrani.com/posts/blob-storage-with-dotnet-mvc/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>&lt;code>Azure blob storage&lt;/code> is a storage solution provided by microsoft. You can store data like images, audio, video, json files, zip files etc etc in the azure.&lt;/p>
&lt;h2 id="what-are-we-going-to-learn">What are we going to learn?&lt;/h2>
&lt;ul>
&lt;li>How to create a web application that stores and manipulate the images in the cloud.&lt;/li>
&lt;li>We will perform all the CRUD (create, read, update and delete) operations.&lt;/li>
&lt;/ul>
&lt;h2 id="tech-used">Tech used&lt;/h2>
&lt;ul>
&lt;li>.NET Core 9 (MVC app)&lt;/li>
&lt;li>SQL server 2022&lt;/li>
&lt;li>Azure storage account&lt;/li>
&lt;/ul>
&lt;h2 id="high-level-overview">High level overview&lt;/h2>
&lt;ul>
&lt;li>We will save &lt;code>image url&lt;/code> in the database and images in the &lt;code>storage account(blob container)&lt;/code>&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h2 id="lets-create-an-storage-account-first">Let&amp;rsquo;s create an storage account first&lt;/h2>
&lt;p>Step 1:
&lt;img src="https://ravindradevrani.com/images/blobstorage/blob_1.png" alt="create azure storage account 1">&lt;/p></description></item><item><title>Cosmos DB For NoSQL - CRUD With Dotnet</title><link>https://ravindradevrani.com/posts/cosmos-db-crud-with-dotnet/</link><pubDate>Sun, 07 Sep 2025 21:37:42 +0530</pubDate><guid>https://ravindradevrani.com/posts/cosmos-db-crud-with-dotnet/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>&lt;code>Azure Cosmos DB for NoSQL&lt;/code> is a fully managed and serverless &lt;code>NoSQL&lt;/code> and &lt;code>vector database&lt;/code> for modern app development, including AI applications and agents. With its SLA-backed speed and availability as well as instant dynamic scalability, it is ideal for real-time NoSQL applications that require high performance and distributed computing over massive volumes of NoSQL and vector data.&lt;/p>
&lt;p>&lt;strong>Soruce:&lt;/strong> learn.microsoft.com, you can learn more about it from &lt;a href="https://learn.microsoft.com/en-us/azure/cosmos-db/nosql/overview">here&lt;/a>&lt;/p></description></item><item><title>Dotnet: All you need to know about middlewares</title><link>https://ravindradevrani.com/posts/middlewares-in-dotnet/</link><pubDate>Tue, 27 May 2025 12:49:04 +0530</pubDate><guid>https://ravindradevrani.com/posts/middlewares-in-dotnet/</guid><description>&lt;!-- raw HTML omitted -->
&lt;ul>
&lt;li>In dotnet, a &lt;code>Middleware&lt;/code> is a piece of code that runs in the request pipeline.&lt;/li>
&lt;li>Middlewares are put together in a sequence, and their order matters.&lt;/li>
&lt;li>When a request is made, it goes through each of the middleware.&lt;/li>
&lt;li>Response flow back in reverse order through the middleware.&lt;/li>
&lt;li>Each middleware has capability to modify the request or short circuits the pipeline.&lt;/li>
&lt;li>Each middleware can change the response before it&amp;rsquo;s sent to the client.&lt;/li>
&lt;/ul>
&lt;p>&lt;img src="https://ravindradevrani.com/images/middleware-in-dotnet.webp" alt="middleware pipeline in .net core">&lt;/p></description></item><item><title>Jwt Authention and role base authorization in Dotnet Core</title><link>https://ravindradevrani.com/posts/jwt-authention-in-dotnet-core/</link><pubDate>Sun, 18 May 2025 17:11:50 +0530</pubDate><guid>https://ravindradevrani.com/posts/jwt-authention-in-dotnet-core/</guid><description>&lt;!-- raw HTML omitted -->
&lt;h2 id="create-a-new-web-api-project">Create a new web api project&lt;/h2>
&lt;p>Run these commands in a sequence to create a new project.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-sh" data-lang="sh">&lt;span style="display:flex;">&lt;span>dotnet new sln -o JwtDotnet9
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>cd JwtDotnet9
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>dotnet sln add JwtDotnet9/JwtDotnet9.csproj
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Open the project in vs code.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-sh" data-lang="sh">&lt;span style="display:flex;">&lt;span>code .
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>=&amp;gt; &lt;a href="https://github.com/rd003/JwtDotnet9">Source Code&lt;/a>&lt;/p>
&lt;p>=&amp;gt; &lt;a href="https://ravindradevrani.com/posts/dotnet-core-jwt-refresh-token/">Securing The .NET 9 App: Signup, Login, JWT, Refresh Tokens, and Role Based Access with PostgreSQL&lt;/a>&lt;/p>
&lt;h2 id="install-the-required-nuget-packages">Install the required nuget packages&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-sh" data-lang="sh">&lt;span style="display:flex;">&lt;span>dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="jwt-configuration-in-appsettings">Jwt configuration in appsettings&lt;/h2>
&lt;p>Open &lt;code>appsettings.json&lt;/code> and add these lines&lt;/p></description></item><item><title>IEnumerable Vs IQueryable In C#</title><link>https://ravindradevrani.com/posts/ienumerable-vs-iqueryable/</link><pubDate>Tue, 13 May 2025 11:45:17 +0530</pubDate><guid>https://ravindradevrani.com/posts/ienumerable-vs-iqueryable/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>There has been a discussion around town about the difference between an &lt;code>IEnumerable&lt;/code> and an &lt;code>IQueryable&lt;/code>, especially in c# interviews. I won&amp;rsquo;t be diving into the fact that &lt;code>IEnumerable&lt;/code> is part of the &lt;code>System.Collections&lt;/code> namespace and &lt;code>IQueryable&lt;/code> belongs to &lt;code>System.Linq&lt;/code> namespace (or did I???). Rather, I’ll focus on the practical usage of both—how they work, and when to use each.&lt;/p>
&lt;h2 id="iqueryable">IQueryable&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-cs" data-lang="cs">&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">public&lt;/span> IActionResult GetPeople()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// It will retrieve 2 records from database &lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> IQueryable&amp;lt;Person&amp;gt; people = _context.People.Take(&lt;span style="color:#ae81ff">2&lt;/span>); 
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// Note: At the above line, no data will be retrieved from the database&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> Ok(people); &lt;span style="color:#75715e">// Data will be retrieved here&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="corresponding-sql">Corresponding sql&lt;/h3>
&lt;p>Note that, I am using &lt;code>Sqlite&lt;/code>, the above code is translated to this query:&lt;/p></description></item><item><title>Bulk insert in dapper with table valued parameter</title><link>https://ravindradevrani.com/posts/bulk-insert-in-dapper-with-table-valued-parameter/</link><pubDate>Sun, 04 May 2025 17:00:00 +0530</pubDate><guid>https://ravindradevrani.com/posts/bulk-insert-in-dapper-with-table-valued-parameter/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>There might be instances when you want to insert bulk data. For an instance, you want to create an order, where you need to add multiple items. Let&amp;rsquo;s see how can we insert bulk data in c# using dapper.&lt;/p>
&lt;p>Note: It is only good for adding bunch of rows. But if you are looking for adding hundreds of rows then better to use other approaches. There are many, if you look out.&lt;/p></description></item><item><title>EF Core under the hood: Count() vs Any()</title><link>https://ravindradevrani.com/posts/count-vs-any-in-entity-framework-core/</link><pubDate>Tue, 01 Apr 2025 11:03:07 +0530</pubDate><guid>https://ravindradevrani.com/posts/count-vs-any-in-entity-framework-core/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>Let&amp;rsquo;s say you want to execute a code block when &lt;code>Book&lt;/code> table is not empty. In Entity Framework Core, we can achieve this in two ways (there might be others but I am unaware of them):&lt;/p>
&lt;p>Option 1:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-cs" data-lang="cs">&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span>(context.Books.Count()&amp;gt;&lt;span style="color:#ae81ff">0&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// do something&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Option 2:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-cs" data-lang="cs">&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> (context.Books.Any())
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// do something&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;strong>Note 📢:&lt;/strong> I am testing these queries against a table containing 1 million rows.&lt;/p></description></item><item><title>How to Install DotNet SDK In Ubuntu Based Distros?</title><link>https://ravindradevrani.com/posts/how-to-install-dotnet-sdk-in-ubuntu-based-distros/</link><pubDate>Wed, 26 Mar 2025 19:59:22 +0530</pubDate><guid>https://ravindradevrani.com/posts/how-to-install-dotnet-sdk-in-ubuntu-based-distros/</guid><description>&lt;h2 id="my-distro">My Distro&lt;/h2>
&lt;p>I am using &lt;code>linux mint 22.1&lt;/code> which is based on &lt;code>Ubuntu 24.04&lt;/code>.&lt;/p>
&lt;h2 id="straightforeward-command">Straightforeward command&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>sudo apt-get update
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>sudo apt-get install -y dotnet-sdk-10.0
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="but">But&amp;hellip;&lt;/h2>
&lt;p>I have tried to run this command &lt;code>sudo apt-get install -y dotnet-sdk-10.0&lt;/code> but unfortunately I got no success. I have found that, this command works only with &lt;code>Ubuntu 24.10&lt;/code>. For &lt;code>Ubuntu 24.04&lt;/code> I need to use different approach.&lt;/p>
&lt;h2 id="uninstall-prior-version-if-exists">Uninstall prior version if exists&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>sudo apt-get remove dotnet-sdk-9.0
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Now, run these commands in a sequence:&lt;/p></description></item><item><title>Dapper: Output Parameter</title><link>https://ravindradevrani.com/posts/dapper-output-param/</link><pubDate>Sun, 23 Mar 2025 00:00:00 +0530</pubDate><guid>https://ravindradevrani.com/posts/dapper-output-param/</guid><description>&lt;h2 id="stored-procedure">Stored procedure&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-sql" data-lang="sql">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">CREATE&lt;/span> &lt;span style="color:#66d9ef">OR&lt;/span> &lt;span style="color:#66d9ef">ALTER&lt;/span> &lt;span style="color:#66d9ef">PROCEDURE&lt;/span> [dbo].[CreateTrackEntry]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">@&lt;/span>EntryDate DATE,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">@&lt;/span>SleptAt DATETIME2,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">@&lt;/span>WokeUpAt DATETIME2,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">@&lt;/span>NapInMinutes SMALLINT,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">@&lt;/span>TotalWorkInMinutes SMALLINT,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">@&lt;/span>Remarks NVARCHAR(&lt;span style="color:#ae81ff">1000&lt;/span>) &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#66d9ef">NULL&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">@&lt;/span>TrackEntryId INT &lt;span style="color:#66d9ef">OUTPUT&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">AS&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">BEGIN&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">-- code removed for brevity
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">END&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>We have a stored procedure that returns &lt;code>TrackEntryId&lt;/code> as an output parameter. Let&amp;rsquo;s see how can we execute it from the dapper?&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;display:grid;">&lt;code class="language-cs" data-lang="cs">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">using&lt;/span> IDbConnection connection = &lt;span style="color:#66d9ef">new&lt;/span> SqlConnection(_connectionString);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">var&lt;/span> parameters = &lt;span style="color:#66d9ef">new&lt;/span> DynamicParameters(trackEntryToCreate);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">// Input params&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>parameters.Add(&lt;span style="color:#e6db74">&amp;#34;@EntryDate&amp;#34;&lt;/span>, trackEntryToCreate.EntryDate);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>parameters.Add(&lt;span style="color:#e6db74">&amp;#34;@SleptAt&amp;#34;&lt;/span>, trackEntryToCreate.SleptAt);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>parameters.Add(&lt;span style="color:#e6db74">&amp;#34;@WokeUpAt&amp;#34;&lt;/span>, trackEntryToCreate.WokeUpAt);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>parameters.Add(&lt;span style="color:#e6db74">&amp;#34;@NapInMinutes&amp;#34;&lt;/span>, trackEntryToCreate.NapInMinutes);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>parameters.Add(&lt;span style="color:#e6db74">&amp;#34;@TotalWorkInMinutes&amp;#34;&lt;/span>, trackEntryToCreate.TotalWorkInMinutes);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>parameters.Add(&lt;span style="color:#e6db74">&amp;#34;@Remarks&amp;#34;&lt;/span>, trackEntryToCreate.Remarks);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">// output params&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex; background-color:#3c3d38">&lt;span>parameters.Add(&lt;span style="color:#e6db74">&amp;#34;@TrackEntryId&amp;#34;&lt;/span>, dbType: DbType.Int32, direction: ParameterDirection.Output);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">await&lt;/span> connection.ExecuteAsync(&lt;span style="color:#e6db74">&amp;#34;CreateTrackEntry&amp;#34;&lt;/span>, parameters,commandType:CommandType.StoredProcedure);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex; background-color:#3c3d38">&lt;span>&lt;span style="color:#66d9ef">int&lt;/span> trackEntryId = parameters.Get&amp;lt;&lt;span style="color:#66d9ef">int&lt;/span>&amp;gt;(&lt;span style="color:#e6db74">&amp;#34;@TrackEntryId&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>Configuring dotnet core apps for OpenApi with SwaggerUi or Scalar</title><link>https://ravindradevrani.com/posts/configuring-dotnet-core-app-for-swagger-ui-or-scalar/</link><pubDate>Fri, 21 Mar 2025 09:16:37 +0530</pubDate><guid>https://ravindradevrani.com/posts/configuring-dotnet-core-app-for-swagger-ui-or-scalar/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>&lt;code>SwaggerUI&lt;/code>, which was previously bundled with .NET Core APIs, has been dropped in .NET 9. However, .NET Core Web APIs still support generating &lt;code>OpenAPI&lt;/code> documents. .NET Core apps have built-in support for generating information about endpoints and it uses &lt;code>Microsoft.AspNetCore.OpenApi&lt;/code> package for that. To configure interactive UIs for these OpenAPI documents, we have several options. We are going to explore these two:&lt;/p>
&lt;ol>
&lt;li>Swashbuckle SwaggerUI&lt;/li>
&lt;li>Scalar&lt;/li>
&lt;/ol>
&lt;h3 id="create-a-new-project-if-does-not-have-an-existing">Create a new project, if does not have an existing&lt;/h3>
&lt;p>Execute these commands in a sequence&lt;/p></description></item><item><title>Transactions in Dapper</title><link>https://ravindradevrani.com/posts/transactions-in-dapper/</link><pubDate>Thu, 20 Mar 2025 09:39:47 +0530</pubDate><guid>https://ravindradevrani.com/posts/transactions-in-dapper/</guid><description>&lt;p>Isn&amp;rsquo;t it already described in Dapper docs? Sure it is. Why do I bother to write this? Am I just wtiting it for the sake of &amp;ldquo;posting&amp;rdquo;? No, I am not. Actually, I was trying to write the code by using Dapper&amp;rsquo;s docs. Unfortunately, I ran into a few bugs. I am using .NET 9, by the way and this is not even a blog post; it&amp;rsquo;s just a code snippet. I thought I should share it, may be someone else is facing the same problem as me.&lt;/p></description></item><item><title>Keyset Pagination In Entity Framework Core</title><link>https://ravindradevrani.com/posts/keyset-pagination-in-ef-core/</link><pubDate>Sat, 15 Mar 2025 09:50:37 +0530</pubDate><guid>https://ravindradevrani.com/posts/keyset-pagination-in-ef-core/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>First we need to know about the traditional offset based pagination and the problems it introduces.&lt;/p>
&lt;h3 id="offset-pagination">Offset pagination&lt;/h3>
&lt;p>In the code below we are using the offset pagination.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-cs" data-lang="cs">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#a6e22e">[HttpGet(&amp;#34;offset&amp;#34;)]&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">async&lt;/span> Task&amp;lt;IActionResult&amp;gt; GetBooks(&lt;span style="color:#66d9ef">int&lt;/span> limit=&lt;span style="color:#ae81ff">10&lt;/span>, &lt;span style="color:#66d9ef">int&lt;/span> page=&lt;span style="color:#ae81ff">1&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">var&lt;/span> books = &lt;span style="color:#66d9ef">await&lt;/span> _context.Books
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> .AsNoTracking()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> .OrderBy(a =&amp;gt; a.Id)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> .Skip(limit * (page - &lt;span style="color:#ae81ff">1&lt;/span>))
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> .Take(limit)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> .ToListAsync();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> Ok(books);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Which translates to the following sql:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-sql" data-lang="sql">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">SELECT&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> [b].[Id],
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> [b].[Author],
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> [b].[Country],
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> [b].[ImageLink],
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> [b].[&lt;span style="color:#66d9ef">Language&lt;/span>],
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> [b].[Link],
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> [b].[Pages],
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> [b].[Price],
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> [b].[Title],
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> [b].[&lt;span style="color:#66d9ef">Year&lt;/span>]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">FROM&lt;/span> [Book] &lt;span style="color:#66d9ef">AS&lt;/span> [b]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">ORDER&lt;/span> &lt;span style="color:#66d9ef">BY&lt;/span> [b].[Id]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">OFFSET&lt;/span> &lt;span style="color:#f92672">@&lt;/span>__p_0 &lt;span style="color:#66d9ef">ROWS&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">FETCH&lt;/span> &lt;span style="color:#66d9ef">NEXT&lt;/span> &lt;span style="color:#f92672">@&lt;/span>__p_1 &lt;span style="color:#66d9ef">ROWS&lt;/span> &lt;span style="color:#66d9ef">ONLY&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;strong>Note:&lt;/strong> In every pagination logic, ordering must be unique. In our case we are using &lt;code>Id&lt;/code> which is unique.&lt;/p></description></item><item><title>Rest Api Designing Best Practices</title><link>https://ravindradevrani.com/posts/rest-api-best-practices-design/</link><pubDate>Fri, 07 Mar 2025 10:41:02 +0530</pubDate><guid>https://ravindradevrani.com/posts/rest-api-best-practices-design/</guid><description>&lt;p>There are some common practices one should take care of while designing REST APIs.&lt;/p>
&lt;blockquote>
&lt;p>There is also a &lt;a href="https://youtu.be/6vWdSQ3iZ2E?si=V3CBjc_ZHLz_4AKS">video version&lt;/a> of this post.&lt;/p>
&lt;/blockquote>
&lt;!-- raw HTML omitted -->
&lt;h3 id="1-use-descriptive-names-for-resources">1. Use descriptive names for resources&lt;/h3>
&lt;ul>
&lt;li>❌ /api/getAllBooks&lt;/li>
&lt;li>❌ /api/retrieveBooks&lt;/li>
&lt;li>❌ /api/manageBooks&lt;/li>
&lt;li>❌ /api/process&lt;/li>
&lt;li>✅ /api/books&lt;/li>
&lt;/ul>
&lt;h3 id="2-use-nouns-not-verbs">2. Use nouns not verbs&lt;/h3>
&lt;ul>
&lt;li>❌ /api/mangage-books&lt;/li>
&lt;li>✅ /api/books&lt;/li>
&lt;/ul>
&lt;h3 id="3-use-plural-nouns">3. Use plural nouns&lt;/h3>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>❌ Singular Nouns&lt;/th>
 &lt;th>✅ Plural Nouns&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>/api/book&lt;/td>
 &lt;td>/api/books&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>/api/movie&lt;/td>
 &lt;td>/api/movies&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>/api/person&lt;/td>
 &lt;td>/api/people&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>/api/customer&lt;/td>
 &lt;td>/api/customers&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h3 id="4-use-hyphens---in-url-for-better-readabilty">4. Use hyphens (-) in url for better readabilty&lt;/h3>
&lt;ul>
&lt;li>❌ /api/useraccounts&lt;/li>
&lt;li>✅ /api/user-accounts&lt;/li>
&lt;/ul>
&lt;h3 id="5-never-use-crud-method-names-in-url">5. Never use crud method names in url&lt;/h3>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>HttpMethod&lt;/th>
 &lt;th>❌❌❌&lt;/th>
 &lt;th>✅✅✅&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>GET&lt;/td>
 &lt;td>/api/books/GetAllBooks&lt;/td>
 &lt;td>/api/books&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>GET&lt;/td>
 &lt;td>/api/books/GetBookById/{id}&lt;/td>
 &lt;td>/api/books/{id}&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>POST&lt;/td>
 &lt;td>/api/books/CreateBook&lt;/td>
 &lt;td>/api/books&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>PUT&lt;/td>
 &lt;td>/api/books/UpdateBook/{id}&lt;/td>
 &lt;td>/api/books/{id}&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>DELETE&lt;/td>
 &lt;td>/api/books/DeleteBook/{id}&lt;/td>
 &lt;td>/api/books/{id}&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h3 id="6-use-http-method-properly">6. Use http method properly&lt;/h3>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>HttpMethod&lt;/th>
 &lt;th>Endpoint&lt;/th>
 &lt;th>Description&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>GET&lt;/td>
 &lt;td>/api/books&lt;/td>
 &lt;td>Indicates a get resources&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>GET&lt;/td>
 &lt;td>/api/books/{id}&lt;/td>
 &lt;td>Indicates a get resource with id&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>POST&lt;/td>
 &lt;td>/api/books&lt;/td>
 &lt;td>Indicates creating a resource&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>PUT&lt;/td>
 &lt;td>/api/books/{id}&lt;/td>
 &lt;td>Indicates updating a resource&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>DELETE&lt;/td>
 &lt;td>/api/books/{id}&lt;/td>
 &lt;td>Indicates deleting a resource&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h3 id="7-use-http-statuscodes-correctly">7. Use Http StatusCodes Correctly&lt;/h3>
&lt;p>These are the most commonly used status codes.&lt;/p></description></item><item><title>Dotnet Service Lifetime : AddTransient(), AddScoped(), AddSingleton()</title><link>https://ravindradevrani.com/posts/dotnet-service-lifetime/</link><pubDate>Wed, 26 Feb 2025 07:29:14 +0530</pubDate><guid>https://ravindradevrani.com/posts/dotnet-service-lifetime/</guid><description>&lt;!-- raw HTML omitted -->
&lt;h2 id="example-setup">Example Setup&lt;/h2>
&lt;p>I am using a &lt;code>MinimalApi&lt;/code> application. Create a new one if you need.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>dotnet new webapi -n DITest
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Open it in a IDE or editor of your choice.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-cs" data-lang="cs">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">interface&lt;/span> &lt;span style="color:#a6e22e">IMyService&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Guid InstanceId { &lt;span style="color:#66d9ef">get&lt;/span>; }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">class&lt;/span> &lt;span style="color:#a6e22e">MyService&lt;/span> : IMyService
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">public&lt;/span> Guid InstanceId { &lt;span style="color:#66d9ef">get&lt;/span>; }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">public&lt;/span> MyService()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> InstanceId = Guid.NewGuid();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// We are logging in the constructor, so that we get notified whenever the instance is created&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Console.WriteLine(&lt;span style="color:#e6db74">$&amp;#34;==&amp;gt; Service created with InstanceId: {InstanceId}&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;code>IMyService&lt;/code> have a read-only property named &lt;code>InstanceId&lt;/code> of type &lt;code>Guid&lt;/code>, which is set from the constructor.
We are logging inside the constructor, so that we can get notified whenever the new instance is created.&lt;/p></description></item><item><title>SingleAsync vs SingleOrDefaultAync vs FirstAsync vs FirstOrDefaultAsync vs FindAync</title><link>https://ravindradevrani.com/posts/singleasync-vs-singleordefaultaync-vs-firstasync-vs-firstordefaultasync-vs-findaync/</link><pubDate>Mon, 24 Feb 2025 18:07:04 +0530</pubDate><guid>https://ravindradevrani.com/posts/singleasync-vs-singleordefaultaync-vs-firstasync-vs-firstordefaultasync-vs-findaync/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>I don’t think there is any need of introduction. Let’s jump to the code section. We coders understand with code more. Let’s understand the concept then you don’t need to remember any definition.&lt;/p>
&lt;p>This is the recordset against which I am running queries.&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>Id&lt;/th>
 &lt;th>FirstName&lt;/th>
 &lt;th>LastName&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>1&lt;/td>
 &lt;td>John&lt;/td>
 &lt;td>Doe&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>2&lt;/td>
 &lt;td>Ravindra&lt;/td>
 &lt;td>Devrani&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>3&lt;/td>
 &lt;td>Mohan&lt;/td>
 &lt;td>Singh&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>20&lt;/td>
 &lt;td>Mahesh&lt;/td>
 &lt;td>Soni&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>21&lt;/td>
 &lt;td>John&lt;/td>
 &lt;td>Snow&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>First and foremost let’s say we need a record with LastName=”Doe”.&lt;/p></description></item><item><title>Database Firsts Approach In EF Core</title><link>https://ravindradevrani.com/posts/db-first-approach-ef-core/</link><pubDate>Mon, 24 Feb 2025 17:49:15 +0530</pubDate><guid>https://ravindradevrani.com/posts/db-first-approach-ef-core/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>I have used &lt;code>database first&lt;/code> approach in the .NET Framework 4.X. But It is the first time I am trying to use Db First approach in the .NET Core (I am using .net 9). Microsoft refers it &lt;a href="https://learn.microsoft.com/en-us/ef/core/managing-schemas/scaffolding/?tabs=dotnet-core-cli">&amp;lsquo;Scaffolding (Reverse Engineering)&amp;rsquo;&lt;/a>. Personally I prefer &lt;code>Dapper&lt;/code> for DB First approach. May be you have an existing database and you want to use it with ENTITY FRAMEWORK, then this approach might be helpful. I am playing around it and documenting it and sharing that journey with you. Let&amp;rsquo;s see what it offers.&lt;/p></description></item><item><title>Creating and Installing Dotnet CLI Tool</title><link>https://ravindradevrani.com/posts/creating-and-installing-dotnet-cli-tool/</link><pubDate>Mon, 24 Feb 2025 13:28:51 +0530</pubDate><guid>https://ravindradevrani.com/posts/creating-and-installing-dotnet-cli-tool/</guid><description>&lt;p>In this tutorial we are going to learn:&lt;/p>
&lt;ul>
&lt;li>How to create a cli tool?&lt;/li>
&lt;li>How to create a nuget package?&lt;/li>
&lt;li>How to install it in our machine.&lt;/li>
&lt;/ul>
&lt;p>CLI tools are very useful, they are very easy to use. We are already using it in our every day.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-sh" data-lang="sh">&lt;span style="display:flex;">&lt;span>dotnet new console -o CliToolDemo
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>It is the example of dotnet cli tool, simple way to create a .net console application. You can also create your own cli tools. We are going to use a package created by Microsoft named &lt;code>System.CommandLine&lt;/code> , which is a pre-released version as of I am writing this blog post. It is a pre-released version for so long, I wonder what are the plans about this package. You can also use a library named &lt;a href="https://github.com/mayuki/Cocona">Cocona&lt;/a> to create cli tools, which is pretty simple and widely popular. But I am going to stick with &lt;code>System.CommandLine&lt;/code> . You should definitely checkout the cocona.&lt;/p></description></item><item><title>Securing The .NET 9 App: Signup, Login, JWT, Refresh Tokens, and Role Based Access with PostgreSQL</title><link>https://ravindradevrani.com/posts/dotnet-core-jwt-refresh-token/</link><pubDate>Mon, 24 Feb 2025 11:35:17 +0530</pubDate><guid>https://ravindradevrani.com/posts/dotnet-core-jwt-refresh-token/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>REST APIs are stateless, so server does not store any information about the client. So we can not authorize the rest application in a traditional way. How does a server knows if the user is authenticated user or not? In this situation the &lt;strong>Json Web Token (JWT)&lt;/strong> saves the day.&lt;/p>
&lt;blockquote>
&lt;p>JSON Web Tokens are an open, industry standard &lt;a href="https://tools.ietf.org/html/rfc7519">&lt;strong>RFC 7519&lt;/strong>&lt;/a> method for representing claims securely between two parties. &lt;a href="https://jwt.io/">Source: jwt.io&lt;/a>&lt;/p></description></item><item><title>Handle Exceptions Globally in .NET Core With IExceptionHandler And IProblemDetailService</title><link>https://ravindradevrani.com/posts/handle-exception-globally-with-iexceptionhandler/</link><pubDate>Sun, 23 Feb 2025 18:16:31 +0530</pubDate><guid>https://ravindradevrani.com/posts/handle-exception-globally-with-iexceptionhandler/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>&lt;strong>Problem details&lt;/strong> is a standard way to communicate error details in &lt;strong>HttpResponse,&lt;/strong> defined in &lt;a href="https://datatracker.ietf.org/doc/html/rfc7807">rfc 7807&lt;/a>. Standard &lt;strong>ProblemDetails&lt;/strong> Properties:&lt;/p>
&lt;ul>
&lt;li>&lt;code>Type&lt;/code>: URI identifying problem type&lt;/li>
&lt;li>&lt;code>Title&lt;/code>: Short error description&lt;/li>
&lt;li>&lt;code>Status&lt;/code>: HTTP status code&lt;/li>
&lt;li>&lt;code>Detail&lt;/code>: Specific error explanation&lt;/li>
&lt;li>&lt;code>Instance&lt;/code>: URI identifying specific error occurrence&lt;/li>
&lt;/ul>
&lt;p>Problem details is automatically integrated with .net core APIs. When we return the &lt;strong>BadRequest&lt;/strong> we generally get response with problem details.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-cs" data-lang="cs">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">// controller method&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">return&lt;/span> BadRequest();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">// response&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#34;type&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;https://tools.ietf.org/html/rfc9110#section-15.5.1&amp;#34;&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#34;title&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;Bad Request&amp;#34;&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#34;status&amp;#34;&lt;/span>: &lt;span style="color:#ae81ff">400&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#34;traceId&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;00-2d4948694b0f223f7f5dff215b42481b-0288bb95d7604783-00&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The same thing happens when we return the &lt;strong>NotFoundException.&lt;/strong>&lt;/p></description></item><item><title>Dotnet Core Api CRUD With Dapper and PostgreSql</title><link>https://ravindradevrani.com/posts/dotnet-core-api-crud-with-dapper-and-postgresql/</link><pubDate>Sun, 23 Feb 2025 18:00:17 +0530</pubDate><guid>https://ravindradevrani.com/posts/dotnet-core-api-crud-with-dapper-and-postgresql/</guid><description>&lt;!-- raw HTML omitted -->
&lt;h4 id="source-code-httpsgithubcomrd003postgressdapperdemohttpsgithubcomrd003postgressdapperdemo">💻Source Code: &lt;a href="https://github.com/rd003/PostgressDapperDemo">https://github.com/rd003/PostgressDapperDemo&lt;/a>&lt;/h4>
&lt;h3 id="tools-and-technology-used">Tools and technology used&lt;/h3>
&lt;ul>
&lt;li>VS Code (editor)&lt;/li>
&lt;li>.Net 8&lt;/li>
&lt;li>Postgres&lt;/li>
&lt;li>Dapper&lt;/li>
&lt;/ul>
&lt;p>Let’s get started with creating the database first.&lt;/p>
&lt;p>create database PersonDb;&lt;/p>
&lt;p>Now, create a table within the database.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-sql" data-lang="sql">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">create&lt;/span> &lt;span style="color:#66d9ef">table&lt;/span> Person
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>(
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Id serial &lt;span style="color:#66d9ef">primary&lt;/span> &lt;span style="color:#66d9ef">key&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Name varchar(&lt;span style="color:#ae81ff">30&lt;/span>) &lt;span style="color:#66d9ef">not&lt;/span> &lt;span style="color:#66d9ef">null&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Email varchar(&lt;span style="color:#ae81ff">30&lt;/span>) &lt;span style="color:#66d9ef">not&lt;/span> &lt;span style="color:#66d9ef">null&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>);
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>To create a new project you need to run these commands in a sequence.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-sh" data-lang="sh">&lt;span style="display:flex;">&lt;span>&amp;gt; dotnet new sln -o PostgressDapperDemo
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt; cd PostgressDapperDemo
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt; dotnet sln add .&lt;span style="color:#ae81ff">\P&lt;/span>ostgressDapperDemo&lt;span style="color:#ae81ff">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#ae81ff">&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt; code . &lt;span style="color:#75715e">#this command will open this project in the vs code&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="nuget-packages">Nuget packages&lt;/h3>
&lt;p>Install the following nuget packages.&lt;/p></description></item><item><title>Unit of Work With Generic Repository in DotNet Core</title><link>https://ravindradevrani.com/posts/unit-of-work-with-generic-repository-in-dotnet-core/</link><pubDate>Sun, 23 Feb 2025 17:38:31 +0530</pubDate><guid>https://ravindradevrani.com/posts/unit-of-work-with-generic-repository-in-dotnet-core/</guid><description>&lt;p>The &lt;strong>Unit of Work&lt;/strong> Pattern is all about coordinated changes to the database. It groups multiple operations, such as inserts, updates, and deletes, into one transaction. This simply means that all the changes are done together as a complete action, or they all don’t happen at all. In case something goes wrong in one of the operations, the whole transaction rolls back and keeps the database consistent by not allowing partial updates. This makes it easy to handle errors and ensures reliable data.&lt;/p></description></item><item><title>Integration Testing in Dotnet With InMemory Db</title><link>https://ravindradevrani.com/posts/integration-testing-in-dotnet-with-in-memory-db/</link><pubDate>Sun, 23 Feb 2025 17:04:04 +0530</pubDate><guid>https://ravindradevrani.com/posts/integration-testing-in-dotnet-with-in-memory-db/</guid><description>&lt;p>&lt;strong>Integration testing&lt;/strong> is a software testing technique, where individual units of a program are integrated together and tested as a group for interacting harmoniously with each other. It concerns the testing of interactions and interfaces between modules, components, or systems to see if they behave as expected once integrated.&lt;/p>
&lt;blockquote>
&lt;p>📢 Always use real database for integration testing instead of InMemory Db.&lt;/p>
&lt;/blockquote>
&lt;h3 id="purpose">Purpose&lt;/h3>
&lt;ul>
&lt;li>This is to ensure that various components or modules behave according to expectation.&lt;/li>
&lt;li>In the case of integration, to find out whether there are problems concerning interfaces or inconsistencies in data.&lt;/li>
&lt;li>Verifying whether it meets the set specifications and functionality of an integrated system.&lt;/li>
&lt;/ul>
&lt;h3 id="tech-used-in-thisproject">Tech Used in this project&lt;/h3>
&lt;ul>
&lt;li>.Net 8 web APIs (controller)&lt;/li>
&lt;li>Sqlite&lt;/li>
&lt;li>EntityFrameworkCore&lt;/li>
&lt;li>xUnit&lt;/li>
&lt;li>In Memory Database (for testing)&lt;/li>
&lt;/ul>
&lt;h3 id="lets-getstarted">Let’s get started&lt;/h3>
&lt;p>Create a &lt;strong>sln&lt;/strong> file (I have named it &lt;strong>PersonGithubActionsDemo&lt;/strong>) with two projects&lt;/p></description></item><item><title>Unit Testing in Dotnet Core With Nsubstitute</title><link>https://ravindradevrani.com/posts/unit-testing-in-dotnet-core-with-nsubstitute/</link><pubDate>Sun, 23 Feb 2025 16:14:13 +0530</pubDate><guid>https://ravindradevrani.com/posts/unit-testing-in-dotnet-core-with-nsubstitute/</guid><description>&lt;p>As the name suggesting , Unit testing is a software testing where smallest units of the application such as methods are tested in the isolation, so that we can ensure our software is working as expected.&lt;/p>
&lt;h3 id="commonly-used-testing-frameworks">Commonly used testing frameworks&lt;/h3>
&lt;ul>
&lt;li>MSTest&lt;/li>
&lt;li>nUnit&lt;/li>
&lt;li>xUnit&lt;/li>
&lt;/ul>
&lt;h3 id="mocking-frameworks">Mocking frameworks&lt;/h3>
&lt;p>Mocking framework is a library which allows us to mock the objects. For example, a &lt;strong>PeopleController&lt;/strong> is injected with the &lt;strong>IPersonRepository.&lt;/strong> While testing the PeopleController, we need the IPersonRepository. Mock frameworks comes to rescue in that situation. With the help of mock frameworks we can mock the IPersonRepository and mimic it’s behavior. Some popular mocking libraries are:&lt;/p></description></item><item><title>.Net Core API CRUD With PostgreSql</title><link>https://ravindradevrani.com/posts/aspnet-core-apis-with-postgres-sql/</link><pubDate>Sun, 23 Feb 2025 13:21:42 +0530</pubDate><guid>https://ravindradevrani.com/posts/aspnet-core-apis-with-postgres-sql/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>When we create an application with .NET, we tend to use the Microsoft tech stack like Visual Studio IDE, Microsoft SQL Server, Windows Operating System, and Azure. However, things have changed since the introduction of .NET Core. We are no longer bound to a specific operating system and database.&lt;/p>
&lt;p>In this blog post, we will learn how to create a Web API CRUD (Create, Read, Update, Delete) application using .NET Core and a Postgres database.&lt;/p></description></item><item><title>Image Upload CRUD Operations in .NET Core WebAPIs</title><link>https://ravindradevrani.com/posts/image-upload-crud-operations-in-dotnet-core-apis/</link><pubDate>Sat, 22 Feb 2025 18:28:32 +0530</pubDate><guid>https://ravindradevrani.com/posts/image-upload-crud-operations-in-dotnet-core-apis/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>Upload images in .net core apis&lt;/p>
&lt;p>In this article, we will learn how to upload/update/delete/read images in .net core APIs. I hate to give long and unnecessary intros, So let’s come to the point’s.&lt;/p>
&lt;p>💻 You can get the code from this &lt;a href="https://github.com/rd003/ImageManipulation_APIs_DotNetCore">github repo&lt;/a>.&lt;/p>
&lt;h2 id="what-is-the-logic-behind-it-">What is the logic behind it? 🤔&lt;/h2>
&lt;p>When you upload the image (or any file), we will generate the unique image name with it’s extension (eg. uniquename.png). Save the image name in the database and save the file with the same name inside the project. In production apps, you can not simply upload files to the server, you have to give permission to that folder. Or you can use other file storage service, where you will save your files.&lt;/p></description></item><item><title>Separating the DI Setup From Program.cs file</title><link>https://ravindradevrani.com/posts/separating-di-setup-from-program-cs-file/</link><pubDate>Sat, 22 Feb 2025 18:18:10 +0530</pubDate><guid>https://ravindradevrani.com/posts/separating-di-setup-from-program-cs-file/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>Let’s take a look at the &lt;strong>program.cs&lt;/strong> file below.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-cs" data-lang="cs">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">using&lt;/span> InventoryMgt.Api.Middlewares;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">using&lt;/span> InventoryMgt.Data.Repositories;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">var&lt;/span> builder = WebApplication.CreateBuilder(args);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">// Add services to the container.&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>builder.Services.AddControllers();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>builder.Services.AddEndpointsApiExplorer();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>builder.Services.AddSwaggerGen();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>builder.Services.AddTransient&amp;lt;ICategoryRepository, CategoryRepository&amp;gt;();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>builder.Services.AddTransient&amp;lt;IProductRepository, ProductRepository&amp;gt;();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>builder.Services.AddTransient&amp;lt;IPurchaseRepository, PurchaseRepository&amp;gt;();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>builder.Services.AddTransient&amp;lt;IStockRepository, StockRepository&amp;gt;();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>builder.Services.AddTransient&amp;lt;ISaleRepository, SaleRepository&amp;gt;();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>builder.Services.AddTransient&amp;lt;ExceptionMiddleware&amp;gt;();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>builder.Services.AddCors(options =&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> options.AddDefaultPolicy(policy =&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> policy.WithOrigins(&lt;span style="color:#e6db74">&amp;#34;*&amp;#34;&lt;/span>).AllowAnyHeader().AllowAnyMethod().WithExposedHeaders(&lt;span style="color:#e6db74">&amp;#34;X-Pagination&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> });
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>});
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">var&lt;/span> app = builder.Build();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">// Configure the HTTP request pipeline.&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">if&lt;/span> (app.Environment.IsDevelopment())
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> app.UseSwagger();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> app.UseSwaggerUI();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>app.UseHttpsRedirection();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>app.UseCors();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>app.UseAuthorization();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>app.ConfigureExceptionMiddleware();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>app.MapControllers();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>app.Run();
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>It is a regular &lt;strong>program.cs&lt;/strong> file. Since we use the dependency injection in our application, we have to register lots of service in our &lt;strong>program.cs&lt;/strong> file. For example:&lt;/p></description></item><item><title>Fluent Validation in Dotnet Core</title><link>https://ravindradevrani.com/posts/fluent-validation-in-dotnet-core/</link><pubDate>Thu, 20 Feb 2025 18:39:45 +0530</pubDate><guid>https://ravindradevrani.com/posts/fluent-validation-in-dotnet-core/</guid><description>&lt;!-- raw HTML omitted -->
&lt;h2 id="fluent-validation">Fluent validation&lt;/h2>
&lt;p>Fluent validation is an open source library for validating the models, which is free as of I am writing this article.&lt;/p>
&lt;p>📢 📝 &lt;strong>Last Updated:&lt;/strong> 25-March-2025&lt;/p>
&lt;h2 id="why-fluent-validation">Why fluent validation?&lt;/h2>
&lt;p>If you already have used data annotation for validation, then you must be aware of the validation in .NET. So you might be thinking why do we need a &lt;code>fluent validation&lt;/code> then.&lt;/p>
&lt;p>&lt;code>Fluent validation&lt;/code> helps you to separate validation logic from your models. That makes your code clean. If you have complex validation logic, then you want to define it separately rather than making your model unreadable.&lt;/p></description></item><item><title>Uploading Images in Blazor Server</title><link>https://ravindradevrani.com/posts/uploading-images-in-blazor-server/</link><pubDate>Thu, 20 Feb 2025 18:25:51 +0530</pubDate><guid>https://ravindradevrani.com/posts/uploading-images-in-blazor-server/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>In this blog post we are going to learn how to upload files in the blazor server application. I am going to upload &lt;strong>images&lt;/strong> in this tutorial but you can upload &lt;strong>any file&lt;/strong> (i have created &lt;strong>reusable code&lt;/strong>).&lt;/p>
&lt;p>💻Source Code: &lt;a href="https://github.com/rd003/BlazorFile/">https://github.com/rd003/BlazorFile/&lt;/a>&lt;/p>
&lt;h2 id="high-leveloverview">High level overview&lt;/h2>
&lt;p>We will upload images to a &lt;strong>folder of a local machine&lt;/strong> ( on a production you have to use cloud storage) with a unique name (e.g. &lt;code>sd$3abccc3$1.png&lt;/code> ), that name is going to save in database.&lt;/p></description></item><item><title>Easiest Way to Handle Csv Files in Csharp</title><link>https://ravindradevrani.com/posts/easiest-way-to-handle-csv-files-in-csharp/</link><pubDate>Thu, 20 Feb 2025 17:58:49 +0530</pubDate><guid>https://ravindradevrani.com/posts/easiest-way-to-handle-csv-files-in-csharp/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>In this tutorial we will se how to read and write data to &lt;strong>csv&lt;/strong> file. It is pretty much easy if you have some external library for that. We are definitely going to use a library and that will be &lt;strong>CsvHelper&lt;/strong>.&lt;/p>
&lt;p>You can also check the video version of this tutorial.&lt;/p>
&lt;p>First and foremost, create a &lt;strong>c# console application&lt;/strong> in .net core. After that we need to install a nuget package, which is&lt;code>**CsvHelper**&lt;/code>&lt;/p></description></item><item><title>Catch Exception Globally in Dotnet Core Apis</title><link>https://ravindradevrani.com/posts/catch-exception-globally-in-dotnet-core-apis/</link><pubDate>Thu, 20 Feb 2025 17:28:02 +0530</pubDate><guid>https://ravindradevrani.com/posts/catch-exception-globally-in-dotnet-core-apis/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>There are to ways of catching exception in .net core, one is using try/catch and other one is catching them globally. Although there is nothing wrong with &lt;strong>try/catch&lt;/strong> blog, it is an elegant way of exception handling. Although you can also catch exceptions globally, If you want to log errors in one place. There are various approaches to achieve this, but we will create the custom middleware to achieve it.&lt;/p></description></item><item><title>Output Caching With Dotnet 7</title><link>https://ravindradevrani.com/posts/output-caching-with-dotnet-7/</link><pubDate>Thu, 20 Feb 2025 16:20:16 +0530</pubDate><guid>https://ravindradevrani.com/posts/output-caching-with-dotnet-7/</guid><description>&lt;!-- raw HTML omitted -->
&lt;h3 id="what-iscaching">What is Caching?&lt;/h3>
&lt;p>Caching is a process of temporarily storing frequently accessed data or
resources in a faster and closer location to the user or application,
with the goal of reducing the time and resources needed to retrieve that
data from its original source. By keeping a copy of the data nearby,
caching enables quicker access and improves the overall performance and
responsiveness of applications.&lt;/p></description></item><item><title>JWT Authentication and Role Based Authorization in Dotnet Core</title><link>https://ravindradevrani.com/posts/jwt-authentication-and-role-based-authorization-in-dotnet-core/</link><pubDate>Thu, 20 Feb 2025 10:31:52 +0530</pubDate><guid>https://ravindradevrani.com/posts/jwt-authentication-and-role-based-authorization-in-dotnet-core/</guid><description>&lt;!-- raw HTML omitted -->
&lt;h2 id="jwt">JWT&lt;/h2>
&lt;p>According to &lt;a href="https://jwt.io/">jwt.io&lt;/a> JSON Web Tokens are an open, industry standard &lt;a href="https://tools.ietf.org/html/rfc7519">&lt;strong>RFC7519&lt;/strong>&lt;/a> method for representing claims securely between two parties.&lt;/p>
&lt;p>When we create REST APIs, then we don&amp;rsquo;t want that any one can access
those apis. REST APIs, will only be accessed by the authenticated user.
We authenticate our user with the help of jwt.&lt;/p>
&lt;p>&lt;strong>How jwt works?&lt;/strong>&lt;/p>
&lt;p>First, we give an authentication endpoint to user, where he/she puts
credential, in return we give a jwt token to user which have an expiry
date. To consume any protected resource, user need to pass jwt token on
authorization header.&lt;/p></description></item><item><title>Create Sln File With Multiple Projects</title><link>https://ravindradevrani.com/posts/create-sln-file-with-multiple-projects/</link><pubDate>Wed, 19 Feb 2025 22:55:02 +0530</pubDate><guid>https://ravindradevrani.com/posts/create-sln-file-with-multiple-projects/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>In this article we will learn how to create a .net core
project with a Solution (sln file) that contains multiple projects. I
know most you guys use visual studio for c# related stuff, but it would
be benificial for person who likes to switch with vs code ocassionally,
like me or who use linux and forced to use .net cli. Although if you are
a new developer and have windows operating system, I will recommend
visual studio, because it is the best possible IDE for c# development.&lt;/p></description></item><item><title>Api Versioning in Dotnet Core</title><link>https://ravindradevrani.com/posts/api-versioning-in-dotnet-core/</link><pubDate>Wed, 19 Feb 2025 22:07:03 +0530</pubDate><guid>https://ravindradevrani.com/posts/api-versioning-in-dotnet-core/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>&lt;a href="https://unsplash.com/@thekidph?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText">Photo by Jan Loyde Cabrera at medium.com&lt;/a>&lt;/p>
&lt;p>When you are going to do some breaking changes in your apis, it is better to create a new version for that, so that user don&amp;rsquo;t freaked out. They still can use the older APIs and get ready for new
changes. There are various way to create a versions of your APIs like&lt;/p>
&lt;ol>
&lt;li>Query string&lt;/li>
&lt;li>URL&lt;/li>
&lt;li>HTTP header&lt;/li>
&lt;/ol>
&lt;blockquote>
&lt;p>If you prefer video version then you can checkout this video with same content.&lt;/p></description></item><item><title>Write dapper effectively with generic methods</title><link>https://ravindradevrani.com/posts/write-dapper-effectively-with-generic-methods/</link><pubDate>Wed, 19 Feb 2025 17:40:41 +0530</pubDate><guid>https://ravindradevrani.com/posts/write-dapper-effectively-with-generic-methods/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>&lt;strong>Dapper&lt;/strong> is a micro ORM for database connectivity in
dotnet and it&amp;rsquo;s been around for quite a while. It is loved by most of
the developers because of its simplicity and performance.&lt;/p>
&lt;h3 id="why-dapper">&lt;strong>Why dapper?&lt;/strong>&lt;/h3>
&lt;p>With the help of dapper you can quickly access the data without writing
too much code. It performs very well because we directly write queries
and executes them. Developers who loves to work with queries and for the
projects, where performance really matters where you wants to write very
optimized queries, dapper can be the good choice.&lt;/p></description></item><item><title>Serilog in .NET</title><link>https://ravindradevrani.com/posts/serilog-in-dotnet/</link><pubDate>Wed, 19 Feb 2025 15:40:41 +0530</pubDate><guid>https://ravindradevrani.com/posts/serilog-in-dotnet/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>In your development journey you have faced so many runtime exceptions. You have handled that with try catch block. But in the runtime you never know where that error has happened and you have to
trace that whole section with putting breakpoints. Sometime you have thought that I wish.. I would get notified whenever that exception occur. Then the logging frameworks comes in the play.&lt;/p></description></item></channel></rss>