<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ Blazor - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ Blazor - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Sun, 14 Jun 2026 10:15:33 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/blazor/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ How to Add Local Storage to Your Blazor Apps with Blazored.LocalStorage ]]>
                </title>
                <description>
                    <![CDATA[ By FADAHUNSI SEYI SAMUEL One critical feature of modern web applications is their ability to store and retrieve data on the client side. This is where local storage comes into play.  In this article, we'll explore how to leverage the power of the Bla... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/use-local-storage-in-blazor-apps/</link>
                <guid isPermaLink="false">66d45edd230dff01669057fb</guid>
                
                    <category>
                        <![CDATA[ Blazor ]]>
                    </category>
                
                    <category>
                        <![CDATA[ C ]]>
                    </category>
                
                    <category>
                        <![CDATA[ localstorage ]]>
                    </category>
                
                    <category>
                        <![CDATA[ .NET ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Mon, 29 Jul 2024 13:55:34 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/07/pexels-pixabay-236698.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By FADAHUNSI SEYI SAMUEL</p>
<p>One critical feature of modern web applications is their ability to store and retrieve data on the <a target="_blank" href="https://www.cloudflare.com/learning/serverless/glossary/client-side-vs-server-side/">client side</a>. This is where <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage">local storage</a> comes into play. </p>
<p>In this article, we'll explore how to leverage the power of the <a target="_blank" href="https://www.nuget.org/packages/Blazored.LocalStorage">Blazored LocalStorage NuGet package</a> to seamlessly integrate <code>local storage</code> capabilities into your Blazor applications.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><a class="post-section-overview" href="#heading-prerequisites">Prerequisites</a></li>
<li><a class="post-section-overview" href="#heading-understanding-local-storage">Understanding Local Storage</a></li>
<li><a class="post-section-overview" href="#heading-introducing-blazoredlocalstorage">Introducing Blazored.LocalStorage</a></li>
<li><a class="post-section-overview" href="#heading-advantages-of-using-blazoredlocalstorage-in-blazor-applications">Advantages of Using Blazored.LocalStorage in Blazor Applications</a></li>
<li><a class="post-section-overview" href="#heading-how-to-install-blazoredlocalstorage">How to Install Blazored.LocalStorage</a></li>
<li><a class="post-section-overview" href="#heading-install-using-the-nuget-package-manager">Install Using Nuget Package Manager</a></li>
<li><a class="post-section-overview" href="#heading-install-using-the-net-cli">Install Using the .NET CLI</a></li>
<li><a class="post-section-overview" href="#heading-how-to-use-blazoredlocalstorage">How to Use Blazored.LocalStorage</a></li>
<li><a class="post-section-overview" href="#heading-advanced-features-and-techniques">Advanced Features and Techniques</a></li>
<li><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></li>
</ul>
<h3 id="heading-prerequisites">Prerequisites</h3>
<p>Make sure you have the necessary tools installed on your computer before continuing with this guide:</p>
<ul>
<li>To build and update <a target="_blank" href="https://learn.microsoft.com/en-us/aspnet/core/blazor/?view=aspnetcore-8.0">Blazor</a> projects, you'll need <a target="_blank" href="https://visualstudio.microsoft.com/downloads/">Visual Studio</a>, a feature-rich Integrated Development Environment (IDE) which you can download from the official <a target="_blank" href="https://visualstudio.microsoft.com/downloads/">Microsoft website here</a>.</li>
<li>The <a target="_blank" href="https://dotnet.microsoft.com/en-us/download">.NET SDK</a> (Software Development Kit) has everything you need to create and execute <a target="_blank" href="https://dotnet.microsoft.com/en-us/learn/dotnet/what-is-dotnet">.NET</a> apps, and it's required for Blazor projects. Make sure your computer has the <code>.NET SDK</code> installed.</li>
<li>Basic knowledge of <a target="_blank" href="https://learn.microsoft.com/en-us/dotnet/csharp/">C#</a> and Blazor.</li>
</ul>
<p>With these installed, will be ready to follow along.</p>
<h2 id="heading-understanding-local-storage">Understanding Local Storage</h2>
<p>Local storage is a <code>key-value</code> pair storage mechanism supported by modern web browsers. It provides a simple way to store data persistently on the user's device. Unlike <code>session storage</code>, which is cleared when the browser session ends, <code>local storage</code> remains intact even after closing the browser window.</p>
<p><a target="_blank" href="https://www.nuget.org/packages/Blazored.LocalStorage">Blazored.LocalStorage</a> is a powerful library that simplifies working with the browser's local storage <code>API</code> (Application Programming Interface) within Blazor applications. It provides a convenient <code>API</code> for storing, retrieving, and managing data in local storage.</p>
<p>By abstracting away the complexities of directly interacting with the <code>localStorage</code> API, this package provides an intuitive and type-safe interface. It lets you focus on building feature-rich Blazor applications without worrying about the underlying storage mechanisms.</p>
<h2 id="heading-introducing-blazoredlocalstorage">Introducing Blazored.LocalStorage</h2>
<p><code>Blazored.LocalStorage</code> is an open-source library designed to provide easy and accessible local storage management in Blazor applications. This library is compatible with both <a target="_blank" href="https://www.pragimtech.com/blog/blazor-webAssembly/what-is-blazor-webassembly/">Blazor WebAssembly</a> and <a target="_blank" href="https://www.c-sharpcorner.com/article/understanding-server-side-blazor/">Blazor Server</a> projects. This makes it a versatile choice for Blazor developers looking to enhance their applications with persistent, client-side storage capabilities.</p>
<p>At its core, <code>Blazored.LocalStorage</code> facilitates the storage and retrieval of data in the browser's local storage, allowing data to persist across browser sessions. </p>
<p>This is particularly useful for storing user preferences, application state, and other data that needs to persist between page reloads without the need for a database or backend storage solution.</p>
<h3 id="heading-advantages-of-using-blazoredlocalstorage-in-blazor-applications">Advantages of Using Blazored.LocalStorage in Blazor Applications</h3>
<p>The inclusion of <code>Blazored.LocalStorage</code> in Blazor applications comes with a host of benefits, including:</p>
<ul>
<li>Simplified State Management: By leveraging local storage, applications can maintain state more effectively across user sessions, enhancing the user experience.</li>
<li>Performance Improvements: Storing data locally reduces the need for frequent server requests, leading to faster application performance and reduced server load.</li>
<li>Enhanced User Experience: Preferences and application states can be preserved, meaning users do not need to reconfigure settings or lose their place in the application upon returning.</li>
<li>Easy Integration: The <code>API</code> provided by <code>Blazored.LocalStorage</code> is designed to be intuitive and straightforward, ensuring that developers can integrate local storage capabilities into their applications with minimal effort.</li>
<li>Cross-Session Persistence: Unlike session storage or in-memory data storage, local storage ensures that data persists across browser sessions and tab closures, providing a more consistent user experience.</li>
</ul>
<h2 id="heading-how-to-install-blazoredlocalstorage">How to Install Blazored.LocalStorage</h2>
<p>Integrating <code>Blazored.LocalStorage</code> into your Blazor project is straightforward, with support for installation via the <code>NuGet Package Manager</code> or the <code>.NET CLI</code> (Command Line Interpreter).</p>
<h3 id="heading-install-using-the-nuget-package-manager">Install Using the NuGet Package Manager</h3>
<p>Using <code>Visual Studio</code>, you can easily add <code>Blazored.LocalStorage</code> by following these steps:</p>
<ul>
<li>Open your Blazor project in Visual Studio.</li>
<li>Navigate to the “Solution Explorer”, right-click on "Dependencies", and select “Manage NuGet Packages”.</li>
</ul>
<p><img src="https://hackmd.io/_uploads/S1ckU8ll0.png" alt="Annotation 2024-04-07 181852" width="600" height="400" loading="lazy"></p>
<ul>
<li>In the NuGet Package Manager, click on the “Browse” tab and search for “Blazored.LocalStorage”.</li>
</ul>
<p><img src="https://hackmd.io/_uploads/HkBjUUxxC.png" alt="2024-04-07_18-22-49" width="600" height="400" loading="lazy"></p>
<ul>
<li>Find the package in the list, select it, and click “Install”.</li>
</ul>
<p>Visual Studio will handle the rest, adding the package to your project along with any dependencies.</p>
<h3 id="heading-install-using-the-net-cli">Install Using the .NET CLI</h3>
<p>For those who prefer using the command line or are working within a development environment other than Visual Studio, the <code>.NET CLI</code> provides a simple method to add <code>Blazored.LocalStorage</code>:</p>
<pre><code class="lang-csharp">dotnet <span class="hljs-keyword">add</span> package Blazored.LocalStorage
</code></pre>
<p>Run the command above in your <code>terminal</code> or <code>command prompt</code> from the root directory of your Blazor project. The CLI will download and install <code>Blazored.LocalStorage</code> along with any necessary dependencies.</p>
<h2 id="heading-how-to-use-blazoredlocalstorage">How to Use Blazored.LocalStorage</h2>
<p>Let's dive into some basic examples of using Blazored.LocalStorage in a Blazor application.</p>
<h3 id="heading-how-to-register-blazoredlocalstorage-in-your-blazor-application">How to Register Blazored.LocalStorage in your Blazor Application</h3>
<p>We will register<code>Blazored.LocalStorage</code> into the root of the application, so that it will be available to use everywhere in the application.</p>
<p>In the <code>program.cs</code> file, which is our root file, we will register the <code>Blazored.LocalStorage</code> service by doing the following:</p>
<pre><code class="lang-csharp">builder.Services.AddBlazoredLocalStorage();
</code></pre>
<p>The code snippet above registers the <code>Blazored.LocalStorage</code> into the application. For this to work, make sure you add the code below to the top of the <code>program.cs</code> file:</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">using</span> Blazored.LocalStorage;
</code></pre>
<p>The code snippet above makes sure that the <code>Blazored.LocalStorage</code> is being imported to be used in the file. If you've added everything correctly, your <code>program.cs</code> file should look like this:</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">using</span> BlazorApp9.Components;
<span class="hljs-keyword">using</span> Blazored.LocalStorage;

<span class="hljs-keyword">namespace</span> <span class="hljs-title">BlazorApp9</span>;

<span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Program</span>
{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Main</span>(<span class="hljs-params"><span class="hljs-keyword">string</span>[] args</span>)</span>
    {
        <span class="hljs-keyword">var</span> builder = WebApplication.CreateBuilder(args);

        builder.Services.AddRazorComponents()
            .AddInteractiveServerComponents();

        builder.Services.AddBlazoredLocalStorage();

        <span class="hljs-keyword">var</span> app = builder.Build();

        <span class="hljs-keyword">if</span> (!app.Environment.IsDevelopment())
        {
            app.UseExceptionHandler(<span class="hljs-string">"/Error"</span>);
            app.UseHsts();
        }

        app.UseHttpsRedirection();

        app.UseStaticFiles();
        app.UseAntiforgery();

        app.MapRazorComponents&lt;App&gt;()
            .AddInteractiveServerRenderMode();

        app.Run();
    }
}
</code></pre>
<p>The above is the full code that should be in your <code>program.cs</code> file. With this, you can now use <code>Blazored.LocalStorage</code> anywhere in the application to store and receive data.</p>
<h3 id="heading-how-to-store-and-retrieve-data-in-blazoredlocalstorage">How to Store and Retrieve Data in Blazored.LocalStorage</h3>
<p>Let's consider a simple scenario where we want to store and retrieve a piece of data using local storage. We'll create a Blazor page with two buttons: one to store data and another to retrieve it.</p>
<pre><code class="lang-csharp">@page <span class="hljs-string">"/"</span>

@inject Blazored.LocalStorage.ILocalStorageService localStorage
@rendermode RenderMode.InteractiveServer

&lt;h3&gt;Local Storage Example&lt;/h3&gt;

&lt;input @bind-<span class="hljs-keyword">value</span>=<span class="hljs-string">"@inputData"</span> /&gt;

&lt;button @onclick=<span class="hljs-string">"StoreData"</span>&gt;Store Data&lt;/button&gt;
&lt;button @onclick=<span class="hljs-string">"RetrieveData"</span>&gt;Retrieve Data&lt;/button&gt;

&lt;p&gt;The retrieved data <span class="hljs-keyword">from</span> the LocalStorage: @storedData &lt;/p&gt;

@code {
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">const</span> <span class="hljs-keyword">string</span> dataKey = <span class="hljs-string">"localStorageKey"</span>;

    <span class="hljs-keyword">private</span> <span class="hljs-keyword">string</span>? storedData;
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">string</span>? inputData;

    <span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-keyword">async</span> Task <span class="hljs-title">StoreData</span>(<span class="hljs-params"></span>)</span>
    {
        <span class="hljs-keyword">if</span>(!<span class="hljs-keyword">string</span>.IsNullOrWhiteSpace(inputData))
        {
            <span class="hljs-keyword">await</span> localStorage.SetItemAsync(dataKey, inputData);
            inputData = <span class="hljs-string">""</span>;
        }
    }

    <span class="hljs-function"><span class="hljs-keyword">protected</span> <span class="hljs-keyword">override</span> <span class="hljs-keyword">async</span> Task <span class="hljs-title">OnAfterRenderAsync</span>(<span class="hljs-params"><span class="hljs-keyword">bool</span> firstRender</span>)</span>
    {
        <span class="hljs-keyword">if</span> (firstRender)
        {
            <span class="hljs-keyword">await</span> RetrieveData();
        }
    }

    <span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-keyword">async</span> Task <span class="hljs-title">RetrieveData</span>(<span class="hljs-params"></span>)</span>
    {
        storedData = <span class="hljs-keyword">await</span> localStorage.GetItemAsync&lt;<span class="hljs-keyword">string</span>&gt;(dataKey);
    }
}
</code></pre>
<p>In the code snippet above, the <code>@inject Blazored.LocalStorage.ILocalStorageService localStorage</code> injects the local storage service to interact with the browser's local storage. The <code>@rendermode RenderMode.InteractiveServer</code> specifies that the page should be rendered as an interactive server-side component. Without the interactive server, the page will not be interactive.</p>
<p>The input field binds to <code>inputData</code> using the <code>@bind-value</code> attribute, allowing users to enter data they wish to store. The <code>dataKey</code> is a constant variable used to store and retrieve data from local storage. The <code>storedData</code> and <code>inputData</code> variables are used to hold the data to be stored and retrieved.</p>
<p>The <code>StoreData</code> method checks to see if <code>inputData</code> is not empty. If not, it stores it in local storage using <code>dataKey</code>, and clears the input field. </p>
<p><code>OnAfterRenderAsync</code> is triggered after the component's first render. It retrieves data from local storage to ensure that data persists even after the page is reloaded. </p>
<p><code>RetrieveData</code> retrieves data from local storage and assigns it to <code>storedData</code> for display.</p>
<p><img src="https://hackmd.io/_uploads/H1DGRAL-0.gif" alt="2024-04-15_00-52-31 (1) (1) (1) (1)" width="600" height="400" loading="lazy"></p>
<p>The video above explains how to store and retrieve data stored in localstorage on the client-side.</p>
<h2 id="heading-advanced-features-and-techniques">Advanced Features and Techniques</h2>
<p>In this section, we'll talk about how you can set an expiration date on your data, and how the stored data can be encrypted and decrypted for security.</p>
<h3 id="heading-how-to-manage-the-expiration-of-stored-data">How to Manage the Expiration of Stored Data</h3>
<p>To manage the expiration of your stored data, you will create a helper class that stores data along with an expiration timestamp. Create a file called <code>StorageItem.cs</code> which will contain the code below:</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">StorageItem</span>&lt;<span class="hljs-title">T</span>&gt;
{
    <span class="hljs-keyword">public</span> required T Data { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
    <span class="hljs-keyword">public</span> DateTime Expiry { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
}
</code></pre>
<p>The code snippet above is a <code>StorageItem&lt;T&gt;</code> class, which is a generic class that can hold data of any type <code>T</code> and an expiry date <code>DateTime</code>. The Data property is required to be set when an instance of <code>StorageItem</code> is created or initialized, ensuring that it always has a valid value. The <code>Expiry</code> property represents the expiration date of the stored data.</p>
<p>Next, you'll create a file which will be a class that contains methods to set and get from the LocalStorage, with an expiration time. Create a file called <code>LocalStorageHelper.cs</code>:</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">using</span> Blazored.LocalStorage;

<span class="hljs-keyword">namespace</span> <span class="hljs-title">BlazorApp9.Components.Helpers</span>;

<span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">class</span> <span class="hljs-title">LocalStorageHelper</span>
{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">async</span> Task <span class="hljs-title">SetItemAsyncWithExpiry</span>&lt;<span class="hljs-title">T</span>&gt;(<span class="hljs-params">ILocalStorageService localStorageService, <span class="hljs-keyword">string</span> key, TimeSpan expiry, T data</span>)</span>
    {
        StorageItem&lt;T&gt; storageItem = <span class="hljs-keyword">new</span> StorageItem&lt;T&gt;
        {
            Data = data,
            Expiry = DateTime.UtcNow.Add(expiry)
        };

        <span class="hljs-keyword">await</span> localStorageService.SetItemAsync(key, storageItem);
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">async</span> <span class="hljs-title">Task</span>&lt;<span class="hljs-title">T</span>?&gt; <span class="hljs-title">GetItemAsyncWithExpiry</span>&lt;<span class="hljs-title">T</span>&gt;(<span class="hljs-params">ILocalStorageService localStorageService, <span class="hljs-keyword">string</span> key</span>)</span>
    {
         <span class="hljs-keyword">var</span> storageItem = <span class="hljs-keyword">await</span> localStorageService.GetItemAsync&lt;StorageItem&lt;T&gt;&gt;(key);

        <span class="hljs-keyword">if</span>(storageItem <span class="hljs-keyword">is</span> <span class="hljs-literal">null</span>) {
            <span class="hljs-keyword">return</span> <span class="hljs-keyword">default</span>;
        }

        <span class="hljs-keyword">if</span> (storageItem.Expiry &lt; DateTime.UtcNow)
        {
            <span class="hljs-keyword">await</span> localStorageService.RemoveItemAsync(key);
            <span class="hljs-keyword">return</span> <span class="hljs-keyword">default</span>;
        }
        <span class="hljs-keyword">return</span> storageItem.Data;
    }
}
</code></pre>
<p>In the code above, you can see the necessary <code>using</code> directive for the <code>Blazored.LocalStorage</code> library. It provides easy access to the browser's local storage from Blazor applications. </p>
<p>This is followed by the declaration of the namespace <code>BlazorApp9.Components.Helpers</code>. This organizes the code and indicates that this helper is part of a specific component's helpers within the Blazor application.</p>
<p>Next, the <code>LocalStorageHelper</code> class is defined as a <code>static</code> class. A static class is one that cannot be instantiated and can only contain static members (using non static methods or properties will not be accepted). </p>
<p>Within the <code>LocalStorageHelper</code> class, two <code>static</code> asynchronous methods are defined: <code>SetItemAsyncWithExpiry</code> and <code>GetItemAsyncWithExpiry</code>.</p>
<p>The <code>SetItemAsyncWithExpiry</code> method is responsible for storing an item in the local storage with an associated expiry time. It accepts an <code>ILocalStorageService</code> instance for interacting with local storage, a <code>key</code> <code>string</code> to identify the stored item, a <code>TimeSpan</code> value representing the expiry duration, and the actual data to be stored. </p>
<p>Inside the method, a <code>StorageItem&lt;T&gt;</code> object is created, where <code>T</code> is the type of data being stored. This object includes the data and the expiry time, which is calculated by adding the specified <code>TimeSpan</code> to the current <a target="_blank" href="https://www.space.com/what-is-utc.html">UTC time</a>. </p>
<p>This <code>StorageItem</code> object is then serialized and saved in local storage under the given key using the <code>SetItemAsync</code> method of <code>ILocalStorageService</code>.</p>
<p>The <code>GetItemAsyncWithExpiry</code> method is responsible for retrieving an item from local storage and checking if it has expired. It also accepts an <code>ILocalStorageService</code> instance and a <code>key</code> <code>string</code>. </p>
<p>This method attempts to retrieve the stored <code>StorageItem&lt;T&gt;</code> object using the <code>key</code>. If the retrieved item is <code>null</code>, it returns the default value for the type <code>T</code> (typically <code>null</code> for reference types and zero or equivalent for value types). </p>
<p>If the item is found but its expiry time is earlier than the current UTC time, it means the item has expired. In this case, the item is removed from the local storage using the <code>RemoveItemAsync</code> method of <code>ILocalStorageService</code>, and the method returns the default value for <code>T</code>. If the item is valid and has not expired, the method returns the stored data.</p>
<h3 id="heading-how-to-implement-encryption-and-decryption">How to Implement Encryption and Decryption</h3>
<p>In this section, we will explore a utility file that provides encryption and decryption functionalities for a Blazor application. </p>
<p>The <code>EncryptionHelper.cs</code> class includes methods for encrypting and decrypting strings, as well as methods for serializing objects to <a target="_blank" href="https://www.w3schools.com/whatis/whatis_json.asp">JSON (Javascript Object Notation)</a> and then encrypting them. This ensures that sensitive data can be securely stored and transmitted. </p>
<p>Let’s dive into the code to understand how these methods work and how you can use them. Add the following code for this file:</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">using</span> System.Security.Cryptography;
<span class="hljs-keyword">using</span> System.Text;
<span class="hljs-keyword">using</span> System.Text.Json;

<span class="hljs-keyword">namespace</span> <span class="hljs-title">BlazorApp9.Components.Helpers</span>;

<span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">class</span> <span class="hljs-title">EncryptionHelper</span>
{
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">readonly</span> <span class="hljs-keyword">string</span> EncryptionKey = <span class="hljs-string">"your-encryption-key"</span>;

    <span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">byte</span>[] <span class="hljs-title">GetKeyBytes</span>(<span class="hljs-params"><span class="hljs-keyword">string</span> key</span>)</span>
    {

        <span class="hljs-keyword">byte</span>[] keyBytes = Encoding.UTF8.GetBytes(key);
        Array.Resize(<span class="hljs-keyword">ref</span> keyBytes, <span class="hljs-number">32</span>);
        <span class="hljs-keyword">return</span> keyBytes;
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">string</span> <span class="hljs-title">Encrypt</span>(<span class="hljs-params"><span class="hljs-keyword">string</span> plainText</span>)</span>
    {
        <span class="hljs-keyword">byte</span>[] iv = <span class="hljs-keyword">new</span> <span class="hljs-keyword">byte</span>[<span class="hljs-number">16</span>];
        <span class="hljs-keyword">byte</span>[] array;

        <span class="hljs-keyword">using</span> (Aes aes = Aes.Create())
        {
            aes.Key = GetKeyBytes(EncryptionKey);
            aes.IV = iv;

            ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV);

            <span class="hljs-keyword">using</span> (MemoryStream memoryStream = <span class="hljs-keyword">new</span> MemoryStream())
            {
                <span class="hljs-keyword">using</span> (CryptoStream cryptoStream = <span class="hljs-keyword">new</span> CryptoStream((Stream)memoryStream, encryptor, CryptoStreamMode.Write))
                {
                    <span class="hljs-keyword">using</span> (StreamWriter streamWriter = <span class="hljs-keyword">new</span> StreamWriter((Stream)cryptoStream))
                    {
                        streamWriter.Write(plainText);
                    }

                    array = memoryStream.ToArray();
                }
            }
        }

        <span class="hljs-keyword">return</span> Convert.ToBase64String(array);
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">string</span> <span class="hljs-title">Decrypt</span>(<span class="hljs-params"><span class="hljs-keyword">string</span> cipherText</span>)</span>
    {
        <span class="hljs-keyword">byte</span>[] iv = <span class="hljs-keyword">new</span> <span class="hljs-keyword">byte</span>[<span class="hljs-number">16</span>];
        <span class="hljs-keyword">byte</span>[] buffer = Convert.FromBase64String(cipherText);

        <span class="hljs-keyword">using</span> (Aes aes = Aes.Create())
        {
            aes.Key = GetKeyBytes(EncryptionKey);
            aes.IV = iv;

            ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV);

            <span class="hljs-keyword">using</span> (MemoryStream memoryStream = <span class="hljs-keyword">new</span> MemoryStream(buffer))
            {
                <span class="hljs-keyword">using</span> (CryptoStream cryptoStream = <span class="hljs-keyword">new</span> CryptoStream((Stream)memoryStream, decryptor, CryptoStreamMode.Read))
                {
                    <span class="hljs-keyword">using</span> (StreamReader streamReader = <span class="hljs-keyword">new</span> StreamReader((Stream)cryptoStream))
                    {
                        <span class="hljs-keyword">return</span> streamReader.ReadToEnd();
                    }
                }
            }
        }
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">string</span> <span class="hljs-title">SerializeAndEncrypt</span>&lt;<span class="hljs-title">T</span>&gt;(<span class="hljs-params">T data</span>)</span>
    {
        <span class="hljs-keyword">var</span> jsonString = JsonSerializer.Serialize(data);
        <span class="hljs-keyword">return</span> Encrypt(jsonString);
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> T <span class="hljs-title">DecryptAndDeserialize</span>&lt;<span class="hljs-title">T</span>&gt;(<span class="hljs-params"><span class="hljs-keyword">string</span> cipherText</span>)</span>
    {
        <span class="hljs-keyword">var</span> json = Decrypt(cipherText);
        <span class="hljs-keyword">return</span> JsonSerializer.Deserialize&lt;T&gt;(json);
    }
}
</code></pre>
<p>The <code>EncryptionHelper</code> class is a static helper class designed for encrypting and decrypting data. This is particularly useful for securing sensitive information in a Blazor application. </p>
<p>The class above defines a <code>static</code> <code>readonly</code> field <code>EncryptionKey</code> which holds the encryption key. This key is crucial for both the encryption and decryption processes. It's important to use a strong and securely stored key.</p>
<p>The <code>GetKeyBytes</code> method converts the string key into a byte array and ensures its length is 32 bytes. This is because <a target="_blank" href="https://www.techtarget.com/searchsecurity/definition/Advanced-Encryption-Standard">the AES encryption</a> algorithm requires a 256-bit key, which is 32 bytes long.</p>
<p>The <code>Encrypt</code> method encrypts a <code>plaintext</code> string using <code>AES</code> encryption. It first creates an initialization vector (IV) of 16 bytes, which is required by the <code>AES</code> algorithm. The method then sets up an <code>AES</code> object with the encryption key and IV, and uses a <code>CryptoStream</code> to write the encrypted data to a memory stream. This encrypted data is then converted to a <code>base64</code> string for easy storage and transmission.</p>
<p>The <code>Decrypt</code> method performs the reverse operation. It converts a <code>base64</code> string back to a byte array, sets up the <code>AES</code> object with the same key and IV, and uses a <code>CryptoStream</code> to read the decrypted data from the memory stream. The result is the original plaintext string.</p>
<p>The <code>EncryptionHelper</code> class provides two methods for handling complex data structures: <code>SerializeAndEncrypt</code> and <code>DecryptAndDeserialize</code>. The <code>SerializeAndEncrypt</code> method first serializes an object to a <code>JSON</code> string using <code>JsonSerializer.Serialize</code>, and then encrypts this <code>JSON</code> string using the <code>Encrypt</code> method. This allows complex objects to be securely stored in an encrypted format.</p>
<p>The <code>DecryptAndDeserialize</code> method decrypts an encrypted <code>JSON</code> string back into its original form and then deserializes it into an object of type T using <code>JsonSerializer.Deserialize</code>. This combination of decryption and deserialization ensures that complex data can be securely retrieved and used within the application.</p>
<h3 id="heading-how-to-connect-the-expiration-and-encryption-to-the-user-interface">How to Connect the Expiration and Encryption to the User Interface</h3>
<p>Now we'll walk through a Blazor component (<code>Home.razor</code>) that allows users to store and retrieve encrypted data in the browser's local storage. This ensures that sensitive information is protected and automatically expires when no longer needed. </p>
<p>This approach combines the ease of local storage with the security of encryption, providing a robust solution for managing user data in web applications. Let's dive into the code to see how it works.</p>
<pre><code class="lang-csharp"> @page <span class="hljs-string">"/"</span>
@using BlazorApp9.Components.Helpers

@inject Blazored.LocalStorage.ILocalStorageService localStorage
@rendermode RenderMode.InteractiveServer

&lt;h3&gt;Local Storage Example&lt;/h3&gt;

&lt;input @bind-<span class="hljs-keyword">value</span>=<span class="hljs-string">"@inputData"</span> /&gt;

&lt;button @onclick=<span class="hljs-string">"StoreData"</span>&gt;Store Data&lt;/button&gt;
&lt;button @onclick=<span class="hljs-string">"RetrieveData"</span>&gt;Retrieve Data&lt;/button&gt;

&lt;p&gt;The retrieved data <span class="hljs-keyword">from</span> the LocalStorage: @storedData &lt;/p&gt;

@code {
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">const</span> <span class="hljs-keyword">string</span> dataKey = <span class="hljs-string">"localStorageKey"</span>;

    <span class="hljs-keyword">private</span> <span class="hljs-keyword">string</span>? storedData;
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">string</span>? inputData;

    <span class="hljs-keyword">bool</span> isDataLoaded = <span class="hljs-literal">false</span>;

    <span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-keyword">async</span> Task <span class="hljs-title">StoreData</span>(<span class="hljs-params"></span>)</span>
    {
        <span class="hljs-keyword">if</span> (!<span class="hljs-keyword">string</span>.IsNullOrWhiteSpace(inputData))
        {
            <span class="hljs-keyword">string</span> encryptData = EncryptionHelper.SerializeAndEncrypt(inputData);
            <span class="hljs-keyword">await</span> LocalStorageHelper.SetItemAsyncWithExpiry(localStorage, dataKey, TimeSpan.FromMinutes(<span class="hljs-number">30</span>), encryptData);
            inputData = <span class="hljs-string">""</span>;
        }
    }

    <span class="hljs-function"><span class="hljs-keyword">protected</span> <span class="hljs-keyword">override</span> <span class="hljs-keyword">async</span> Task <span class="hljs-title">OnAfterRenderAsync</span>(<span class="hljs-params"><span class="hljs-keyword">bool</span> firstRender</span>)</span>
    {
        <span class="hljs-keyword">if</span> (firstRender &amp;&amp; !isDataLoaded)
        {
            <span class="hljs-keyword">await</span> RetrieveData();
            isDataLoaded = <span class="hljs-literal">true</span>;
            StateHasChanged();
        }
    }

    <span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-keyword">async</span> Task <span class="hljs-title">RetrieveData</span>(<span class="hljs-params"></span>)</span>
    {
        <span class="hljs-keyword">string</span> encryptData = <span class="hljs-keyword">await</span> LocalStorageHelper.GetItemAsyncWithExpiry&lt;<span class="hljs-keyword">string</span>&gt;(localStorage, dataKey);
        storedData = encryptData != <span class="hljs-literal">null</span> ? EncryptionHelper.DecryptAndDeserialize&lt;<span class="hljs-keyword">string</span>&gt;(encryptData) : <span class="hljs-string">"Data not found or expired."</span>;
    }
}
</code></pre>
<p>In the code above, the <code>StoreData</code> method checks if <code>inputData</code> is valid, encrypts it using <code>EncryptionHelper.SerializeAndEncrypt</code>, and stores it in local storage with a thirty-minute expiry using <code>LocalStorageHelper.SetItemAsyncWithExpiry</code>. The input field is then cleared.</p>
<p>The <code>OnAfterRenderAsync</code> method retrieves data from local storage after the component's initial render. This ensures previously stored data is loaded when the page first displays. It runs once, setting <code>isDataLoaded</code> to true and calling <code>StateHasChanged</code> to update the user interface (UI).</p>
<p>The <code>RetrieveData</code> method fetches data from local storage using <code>LocalStorageHelper.GetItemAsyncWithExpiry</code>. If the data is found and valid, it decrypts and deserializes it using <code>EncryptionHelper.DecryptAndDeserialize</code>. If not, it sets <code>storedData</code> to "<code>Data not found or expired.</code>"</p>
<p><img src="https://hackmd.io/_uploads/BJRDqJUNR.gif" alt="2024-05-30_11-18-37 (1) (2) (1)" width="600" height="400" loading="lazy"></p>
<p>The video above demonstrates how you can implement the concepts discussed in this guide in a web application.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p><code>Blazored.LocalStorage</code> offers a powerful and easy-to-use solution for managing user information in Blazor applications. Its integration brings numerous benefits, including enhanced state management, improved performance, and a better user experience.</p>
<p>After reading through this article and trying out the code for yourself, you should be able to incorporate local storage capabilities into any Blazor project. This will help you unlock the full potential of client-side storage in your web applications.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Learn Blazor WebAssembly and Web API on .NET 6 by Building a Shopping Cart App ]]>
                </title>
                <description>
                    <![CDATA[ Blazor WebAssembly is a single-page app framework for building interactive client-side web apps with .NET. It uses open web standards without plugins or recompiling code into other languages. We just published a full course on the freeCodeCamp.org Yo... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/learn-blazor-webassembly-and-web-api-on-net-6-by-building-a-shopping-cart-app/</link>
                <guid isPermaLink="false">66b20404f31aa965000e5852</guid>
                
                    <category>
                        <![CDATA[ Blazor ]]>
                    </category>
                
                    <category>
                        <![CDATA[ youtube ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Beau Carnes ]]>
                </dc:creator>
                <pubDate>Thu, 28 Apr 2022 17:28:46 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/04/blazorwa.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Blazor WebAssembly is a single-page app framework for building interactive client-side web apps with .NET. It uses open web standards without plugins or recompiling code into other languages.</p>
<p>We just published a full course on the freeCodeCamp.org YouTube channel that will teach you how to use Blazor WebAssembly and Web API on .NET 6.</p>
<p>In this course you will learn step-by-step how to build a shopping cart application.<br>This course also provides a guide on how to integrate a payment gateway into your Blazor WebAssembly component, so that a user is able to pay for products through your application using a debit or credit card or PayPal account.</p>
<p>Gavin Lon teaches this course. Gavin is a senior software engineer with over 20 years of experience. </p>
<p>Here are all the sections covered in this course:</p>
<ul>
<li>Create the Database using EF Core Code First Database Migrations</li>
<li>Retrieve Product Data from Database (Web API component)</li>
<li>Create Classes for Data Transfer Objects (DTOs)</li>
<li>Create ProductRepository Class (Repository Design Pattern)</li>
<li>Create ProductController Class</li>
<li>Create DtoConversion Class (DTO Conversion Extension methods)</li>
<li>Display Product Data to User (Blazor WebAssembly Component)</li>
<li>Display Data for Specific Product to User (Web API and Blazor)</li>
<li>Add Product to Shopping Cart (Web API and Blazor)</li>
<li>Remove Product from Shopping Cart (Web API and Blazor)</li>
<li>Update the Quantity of Products in the Shopping Cart (Web API, Blazor, Blazor JavaScript Interoperability)</li>
<li>Update the Header Menu in Response to a Change to the State of the Shopping Cart (Creating Custom Events in Blazor)</li>
<li>Integration of PayPal Payment Gateway into Blazor Component</li>
<li>Dynamically Populate the Side-Bar Menu (Web API and Blazor)</li>
<li>Optimise Code for Performance (Web API and Blazor)</li>
<li>Use Include Extension Method in LINQ Query (Web API)</li>
<li>User Local Storage Functionality (Blazor)</li>
</ul>
<p>Watch the full course below or on <a target="_blank" href="https://www.youtube.com/watch?v=sHuuo9L3e5c">the freeCodeCamp.org YouTube channel</a> (6-hour watch).</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/sHuuo9L3e5c" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Implement Azure Serverless with Blazor WebAssembly ]]>
                </title>
                <description>
                    <![CDATA[ By Ankit Sharma Introduction In this article, we will learn how to implement Azure serverless with Blazor web assembly. And to do that, we will create an app that lists out some Frequently Asked Questions (FAQ) on Covid-19.  Here's what we will cover... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-implement-azure-serverless-with-blazor-web-assembly/</link>
                <guid isPermaLink="false">66d45db7182810487e0ce0eb</guid>
                
                    <category>
                        <![CDATA[ Azure ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Azure Functions ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Blazor ]]>
                    </category>
                
                    <category>
                        <![CDATA[ C# ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Mon, 06 Jul 2020 13:32:00 +0000</pubDate>
                <media:content url="https://cdn-media-2.freecodecamp.org/w1280/5f9c99da740569d1a4ca220f.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Ankit Sharma</p>
<h2 id="heading-introduction"><strong>Introduction</strong></h2>
<p>In this article, we will learn how to implement Azure serverless with Blazor web assembly. And to do that, we will create an app that lists out some Frequently Asked Questions (FAQ) on Covid-19. </p>
<p>Here's what we will cover:</p>
<ul>
<li>We will create an Azure Cosmos DB which will act as our primary database to store questions and answers. </li>
<li>We will use an Azure function app to fetch data from cosmos DB. </li>
<li>We will deploy the function app to Azure to expose it globally via an API endpoint. </li>
<li>And lastly, we will consume the API in a Blazor web assembly app. </li>
</ul>
<p>The FAQs will be displayed in a card layout with the help of Bootstrap.</p>
<p>The Covid-19 FAQ app is deployed on Azure. See it in action at <a target="_blank" href="https://covid19-faq.azurewebsites.net/">https://covid19-faq.azurewebsites.net/</a></p>
<h2 id="heading-what-is-a-serverless-architecture"><strong>What is a serverless architecture?</strong></h2>
<p>In traditional applications such as a 3-tier app, a client requests resources from the server, and the server processes the request and responds with the appropriate data.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/07/ServerArchi.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>However, there are some issues with this architecture. We need a server running continuously. Even if there are no requests, the server is present 24X7, ready to process the request. Maintaining server availability is cost-intensive. </p>
<p>Another problem is scaling. If the traffic is huge, we need to scale out all the servers which can be a cumbersome process.</p>
<p>An effective solution to this problem is serverless web architecture. The client makes a request to a file storage account instead of a server. The storage account returns the <code>index.html</code> page along with some code that needs to be rendered on the browser. </p>
<p>Since there is no server to render the page, we are relying on the browser to render the page. All the logic to draw the element or update the element will run in the browser. We do not have any server on backend – we just have a storage account with a static asset.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/07/ServerLessArchi.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>This is a cost-effective solution as we do not have any server, just some static files in a storage account. It is also very easy to scale out for heavy load websites.</p>
<h2 id="heading-what-is-an-azure-function"><strong>What is an Azure function?</strong></h2>
<p>Making the browser run all the logic to render the page seems exciting, but it has some limitations. </p>
<p>We do not want the browser to make database calls. We need some part of our code to run on the server-side such as connecting to a database. </p>
<p>This is where Azure functions come in handy. In a serverless architecture, if we want some code to run the server-side, then we use an Azure function.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/07/ServerLessArchiAZFunc.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Azure functions are an event-driven serverless compute platform. You need to pay only when execution happens. They are also easy to scale. Hence, we get both the scaling and the cost benefits with Azure functions. </p>
<p>To learn more you can refer to the <a target="_blank" href="https://azure.microsoft.com/en-in/services/functions/">Azure function official docs</a>.</p>
<h2 id="heading-why-should-you-use-azure-serverless"><strong>Why should you use Azure serverless?</strong></h2>
<p>An Azure serverless solution can add value to your product by minimizing the time and resources you spend on infrastructure-related requirements. </p>
<p>You can increase developer productivity, optimize resources and accelerate the time to market with the help of a fully managed, end-to-end Azure serverless solution.</p>
<p>To learn more, see the <a target="_blank" href="https://azure.microsoft.com/en-in/solutions/serverless/">Azure serverless official doc</a>.</p>
<h2 id="heading-what-is-blazor"><strong>What is Blazor?</strong></h2>
<p>Blazor is a .NET web framework for creating client-side applications using C#/Razor and HTML. </p>
<p>Blazor runs in the browser with the help of <a target="_blank" href="http://webassembly.org/">WebAssembly</a>. It can simplify the process of creating a single page application (SPA). It also provides a full-stack web development experience using .NET.</p>
<p>Using .NET for developing Client-side application has multiple advantages:</p>
<ul>
<li>.NET offers a range of API and tools across all platforms that are stable and easy to use.</li>
<li>The modern languages such as C# and F# offer a lot of features that make programming easier and interesting for developers.</li>
<li>The availability of one of the best IDE in the form of Visual Studio provides a great .NET development experience across multiple platforms such as Windows, Linux, and macOS.</li>
<li>.NET provides features such as speed, performance, security, scalability, and reliability in web development that makes full-stack development easier.</li>
</ul>
<h2 id="heading-why-should-you-use-blazor"><strong>Why should you use Blazor?</strong></h2>
<p>Blazor supports a wide array of features to make web development easier for us. Some of the prominent features of Blazor are:</p>
<ul>
<li><strong>Component-based architecture</strong>: Blazor provides us with a component-based architecture to create rich and composable UI.</li>
<li><strong>Dependency injection</strong>: This allows us to use services by injecting them into components.</li>
<li><strong>Layouts</strong>: We can share common UI elements (for example, menus) across pages using the layouts feature.</li>
<li><strong>Routing</strong>: We can redirect the client request from one component to another with the help of routing.</li>
<li><strong>JavaScript interop</strong>: This allows us to invoke a C# method from JavaScript, and we can call a JavaScript function or API from C# code.</li>
<li><strong>Globalization and localization</strong>: The application can be made accessible to users in multiple cultures and languages</li>
<li><strong>Live reloading</strong>: Live reloading of the app in the browser during development.</li>
<li><strong>Deployment</strong>: We can deploy the Blazor application on IIS and Azure Cloud.</li>
</ul>
<p>To learn more about Blazor, please refer to the <a target="_blank" href="http://blazor.net/">official Blazor docs</a>.</p>
<h2 id="heading-prerequisites"><strong>Prerequisites</strong></h2>
<p>To get started with the application, we need to fulfill these prerequisites:</p>
<ul>
<li>An Azure subscription account. You can create a free Azure account at <a target="_blank" href="https://azure.microsoft.com/en-in/free/">https://azure.microsoft.com/en-in/free/</a></li>
<li>Install the latest version of Visual Studio 2019 from <a target="_blank" href="https://visualstudio.microsoft.com/downloads/">https://visualstudio.microsoft.com/downloads/</a></li>
</ul>
<p>While installing the VS 2019, please make sure you select the Azure development and ASP.NET and web development workload.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/07/VSInstall.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-source-code"><strong>Source Code</strong></h2>
<p>You can get the source code from <a target="_blank" href="https://github.com/AnkitSharma-007/azure-serverless-with-blazor">GitHub here</a>.</p>
<h2 id="heading-create-azure-cosmos-db-account"><strong>Create Azure Cosmos DB account</strong></h2>
<p>Log in to the Azure portal and search for the “Azure Cosmos DB” in the search bar and click on the result. On the next screen, click on the Add button. </p>
<p>This will open a “Create Azure Cosmos DB Account” page. You need to fill in the required information to create your database. Refer to the image shown below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/07/CreateCosmosDBAccount.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>You can fill in the details like this:</p>
<ul>
<li><strong>Subscription</strong>: Select your Azure subscription name from the drop-down.</li>
<li><strong>Resource Group</strong>: Select an existing Resource Group or create a new one.</li>
<li><strong>Account Name</strong>: Enter a unique name for your Azure Cosmos DB account. The name can contain only lowercase letters, numbers, and the ‘-‘ character, and must be between 3 and 44 characters.</li>
<li><strong>API</strong>: Select Core (SQL)</li>
<li><strong>Location</strong>: Select a location to host your Azure Cosmos DB account.</li>
</ul>
<p>Keep the other fields to its default value and click on the “Review+ Create” button. In the next screen, review all your configurations and click on the “Create” button. After a few minutes, the Azure Cosmos DB account will be created. Click on “Go to resource” to navigate to the Azure Cosmos DB account page.</p>
<h2 id="heading-set-up-the-database"><strong>Set up the Database</strong></h2>
<p>On the Azure Cosmos DB account page, click on “Data Explorer” on the left navigation, and then select “New Container”. Refer to the image shown below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/07/CreateContainer.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>An “Add Container” pane will open. You need to fill in the details to create a new container for your Azure Cosmos DB. Refer to the image shown below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/07/ConfigureContainer.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>You can fill in the details as indicated below.</p>
<ul>
<li><strong>Database ID:</strong> You can give any name to your database. Here I am using FAQDB.</li>
<li><strong>Throughput:</strong> Keep it at the default value of 400</li>
<li><strong>Container ID:</strong> Enter the name for your container. Here I am using FAQContainer.</li>
<li><strong>Partition key:</strong> The Partition key is used to automatically partition data among multiple servers for scalability. Put the value as “/id”.</li>
</ul>
<p>Click on the “OK” button to create the database.</p>
<h2 id="heading-add-sample-data-to-the-cosmos-db"><strong>Add Sample data to the Cosmos DB</strong></h2>
<p>In the Data Explorer, expand the FAQDB database then expand the FAQContainer. Select Items, and then click on New Item on the top. An editor will open on the right side of the page. Refer to the image shown below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/07/AddItem.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Put the following JSON data in the editor and click on the Save button at the top.</p>
<pre><code class="lang-json">{
    <span class="hljs-attr">"id"</span>: <span class="hljs-string">"1"</span>,
    <span class="hljs-attr">"question"</span>: <span class="hljs-string">"What is corona virus?"</span>,
    <span class="hljs-attr">"answer"</span>: <span class="hljs-string">"Corona viruses are a large family of viruses which may cause illness in animals or humans. The most recently discovered coronavirus causes coronavirus disease COVID-19."</span>
}
</code></pre>
<p>We have added a set of questions and answer along with a unique id.</p>
<p>Follow the process described above to insert five more sets of data.</p>
<pre><code class="lang-json">{
    <span class="hljs-attr">"id"</span>: <span class="hljs-string">"2"</span>,
    <span class="hljs-attr">"question"</span>: <span class="hljs-string">"What is COVID-19?"</span>,
    <span class="hljs-attr">"answer"</span>: <span class="hljs-string">"COVID-19 is the infectious disease caused by the most recently discovered corona virus. This new virus and disease were unknown before the outbreak began in Wuhan, China, in December 2019."</span>
}
{
    <span class="hljs-attr">"id"</span>: <span class="hljs-string">"3"</span>,
    <span class="hljs-attr">"question"</span>: <span class="hljs-string">"What are the symptoms of COVID-19?"</span>,
    <span class="hljs-attr">"answer"</span>: <span class="hljs-string">"The most common symptoms of COVID-19 are fever, tiredness, and dry cough. Some patients may have aches and pains, nasal congestion, runny nose, sore throat or diarrhea. These symptoms are usually mild and begin gradually. Some people become infected but don’t develop any symptoms and don't feel unwell."</span>
}
{
    <span class="hljs-attr">"id"</span>: <span class="hljs-string">"4"</span>,
    <span class="hljs-attr">"question"</span>: <span class="hljs-string">"How does COVID-19 spread?"</span>,
    <span class="hljs-attr">"answer"</span>: <span class="hljs-string">"People can catch COVID-19 from others who have the virus. The disease can spread from person to person through small droplets from the nose or mouth which are spread when a person with COVID-19 coughs or exhales. These droplets land on objects and surfaces around the person. Other people then catch COVID-19 by touching these objects or surfaces, then touching their eyes, nose or mouth."</span>
}
{
    <span class="hljs-attr">"id"</span>: <span class="hljs-string">"5"</span>,
    <span class="hljs-attr">"question"</span>: <span class="hljs-string">"What can I do to protect myself and prevent the spread of disease?"</span>,
    <span class="hljs-attr">"answer"</span>: <span class="hljs-string">"You can reduce your chances of being infected or spreading COVID-19 by taking some simple precaution. Regularly and thoroughly clean your hands with an alcoholbased hand rub or wash them with soap and water. Maintain at least 1 metre (3 feet) distance between yourself and anyone who is coughing or sneezing. Make sure you, and the people around you, follow good respiratory hygiene. This means covering your mouth and nose with your bent elbow or tissue when you cough or sneeze. Stay home if you feel unwell. If you have a fever, cough and difficulty breathing, seek medical attention and call in advance."</span>
}
{
    <span class="hljs-attr">"id"</span>: <span class="hljs-string">"6"</span>,
    <span class="hljs-attr">"question"</span>: <span class="hljs-string">"Are antibiotics effective in preventing or treating the COVID-19?"</span>,
    <span class="hljs-attr">"answer"</span>: <span class="hljs-string">"No. Antibiotics do not work against viruses, they only work on bacterial infections. COVID-19 is caused by a virus, so antibiotics do not work."</span>
}
</code></pre>
<h2 id="heading-get-the-connection-string"><strong>Get the connection string</strong></h2>
<p>Click on “keys” on the left navigation, navigate to the “Read-write Keys” tab. The value under <code>PRIMARY CONNECTION STRING</code> is our required connection string. Refer to the image shown below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/07/CosmosDBContString.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Make a note of the <code>PRIMARY CONNECTION STRING</code> value. We will use it in the latter part of this article, when we will access the Azure Cosmos DB from an Azure function.</p>
<h2 id="heading-create-an-azure-function-app"><strong>Create an Azure function app</strong></h2>
<p>Open Visual Studio 2019, click on “Create a new project”. Search “Functions” in the search box. Select the Azure Functions template and click on Next. Refer to the image shown below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/07/CreateAzFunction.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>In “Configure your new project” window, enter a Project name as <code>FAQFunctionApp</code>. Click on the Create button. Refer to the image below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/07/CreateAzFunction_1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>A new “Create a new Azure Function Application settings” window will open. Select “Azure Functions v3 (.NET Core)”from the dropdown at the top. Select the function template as “HTTP trigger”. Set the authorization level to “Anonymous” from the drop-down on the right. Click on the Create button to create the function project and HTTP trigger function. </p>
<p>Refer to the image shown below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/07/CreateAzFunction_2.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-install-package-for-azure-cosmos-db"><strong>Install package for Azure Cosmos DB</strong></h2>
<p>To enable the Azure function App to bind to the Azure Cosmos DB, we need to install the <code>Microsoft.Azure.WebJobs.Extensions.CosmosDB</code> package. Navigate to Tools &gt;&gt; NuGet Package Manager &gt;&gt; Package Manager Console and run the following command:</p>
<pre><code>Install-Package Microsoft.Azure.WebJobs.Extensions.CosmosDB
</code></pre><p>Refer to the image shown below.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/07/InstallNuget.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>You can learn more about this package at the <a target="_blank" href="https://www.nuget.org/packages/Microsoft.Azure.WebJobs.Extensions.CosmosDB">NuGet gallery</a>.</p>
<h2 id="heading-configure-the-azure-function-app"><strong>Configure the Azure Function App</strong></h2>
<p>The Azure function project contains a default file called <code>Function1.cs</code>. You can safely delete this file as we won’t be using this for our project.</p>
<p>Right-click on the <code>FAQFunctionApp</code> project and select Add &gt;&gt; New Folder. Name the folder as Models. Again, right-click on the Models folder and select Add &gt;&gt; Class to add a new class file. Put the name of your class as <code>FAQ.cs</code> and click Add.</p>
<p>Open <code>[FAQ.cs](https://github.com/AnkitSharma-007/azure-serverless-with-blazor/blob/master/FAQFunctionApp/FAQFunctionApp/Models/FAQ.cs)</code> and put the following code inside it.</p>
<pre><code class="lang-c#"><span class="hljs-keyword">namespace</span> <span class="hljs-title">FAQFunctionApp.Models</span>
{
    <span class="hljs-keyword">class</span> <span class="hljs-title">FAQ</span>
    {
        <span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> Id { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
        <span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> Question { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
        <span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> Answer { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
    }
}
</code></pre>
<p>The class has the same structure as the JSON data we have inserted in the cosmos DB.</p>
<p>Right-click on the <code>FAQFunctionApp</code> project and select Add &gt;&gt; Class. Name your class as <code>[CovidFAQ.cs](https://github.com/AnkitSharma-007/azure-serverless-with-blazor/blob/master/FAQFunctionApp/FAQFunctionApp/CovidFAQ.cs)</code>. Put the following code inside it.</p>
<pre><code class="lang-c#"><span class="hljs-keyword">using</span> Microsoft.AspNetCore.Mvc;
<span class="hljs-keyword">using</span> System.Collections.Generic;
<span class="hljs-keyword">using</span> Microsoft.AspNetCore.Http;
<span class="hljs-keyword">using</span> Microsoft.Extensions.Logging;
<span class="hljs-keyword">using</span> Microsoft.Azure.WebJobs;
<span class="hljs-keyword">using</span> FAQFunctionApp.Models;
<span class="hljs-keyword">using</span> Microsoft.Azure.WebJobs.Extensions.Http;
<span class="hljs-keyword">using</span> System.Threading.Tasks;

<span class="hljs-keyword">namespace</span> <span class="hljs-title">FAQFunctionApp</span>
{
    <span class="hljs-keyword">class</span> <span class="hljs-title">CovidFAQ</span>
    {
        [<span class="hljs-meta">FunctionName(<span class="hljs-meta-string">"covidFAQ"</span>)</span>]
        <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">async</span> Task&lt;IActionResult&gt; <span class="hljs-title">Run</span>(<span class="hljs-params">
        [HttpTrigger(AuthorizationLevel.Anonymous, <span class="hljs-string">"get"</span>, Route = <span class="hljs-literal">null</span></span>)] HttpRequest req,
        [<span class="hljs-title">CosmosDB</span>(<span class="hljs-params">
            databaseName:<span class="hljs-string">"FAQDB"</span>,
            collectionName:<span class="hljs-string">"FAQContainer"</span>,
            ConnectionStringSetting = <span class="hljs-string">"DBConnectionString"</span>
            </span>)] IEnumerable&lt;FAQ&gt; questionSet, 
        ILogger log)</span>
        {
            log.LogInformation(<span class="hljs-string">"Data fetched from FAQContainer"</span>);
            <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> OkObjectResult(questionSet);
        }
    }
}
</code></pre>
<p>We have created a class <code>CovidFAQ</code> and added an Azure function to it. The attribute <code>FunctionName</code> is used to specify the name of the function. We have used the <code>HttpTrigger</code> attribute which allows the function to be triggered via an HTTP call. The attribute <code>CosmosDB</code> is used to connect to the Azure Cosmos DB. We have defined three parameters for this attribute as described below:</p>
<ul>
<li><strong>databaseName</strong>: the name for the cosmos DB</li>
<li><strong>collectionName</strong>: the collecting inside the cosmos DB we want to access</li>
<li><strong>ConnectionStringSetting</strong>: the connection string to connect to Cosmos DB. We will configure it in the next section.</li>
</ul>
<p>We have decorated the parameter <code>questionSet</code>, which is of type <code>IEnumerable&lt;FAQ&gt;</code> with the <code>CosmosDB</code> attribute. When the app is executed, the parameter <code>questionSet</code> will be populated with the data from Cosmos DB. The function will return the data using a new instance of <code>OkObjectResult</code>.</p>
<h2 id="heading-add-the-connection-string-to-the-azure-function"><strong>Add the connection string to the Azure Function</strong></h2>
<p>Remember the Azure cosmos DB connection string you noted earlier? Now we will configure it for our app. Open the <code>local.settings.json</code> file and add your connection string as shown below:</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"IsEncrypted"</span>: <span class="hljs-literal">false</span>,
  <span class="hljs-attr">"Values"</span>: {
    <span class="hljs-attr">"AzureWebJobsStorage"</span>: <span class="hljs-string">"UseDevelopmentStorage=true"</span>,
    <span class="hljs-attr">"FUNCTIONS_WORKER_RUNTIME"</span>: <span class="hljs-string">"dotnet"</span>,
    <span class="hljs-attr">"DBConnectionString"</span>: <span class="hljs-string">"your connectionn string"</span>
  }
}
</code></pre>
<blockquote>
<p>The local.settings.json will not be published to Azure when we publish the Azure Function app. Therefore, we need to configure the connections string separately while publishing the app to Azure. We will see this in action in the latter part of this article.</p>
</blockquote>
<h2 id="heading-test-the-azure-function-locally"><strong>Test the Azure Function locally</strong></h2>
<p>Press F5 to execute the function. Copy the URL of your function from the Azure Functions runtime output. Refer to the image shown below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/07/ExecuteLocal-1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Open the browser and paste the URL in the browser’s address bar. You can see the output as shown below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/07/ExecuteLocal-2.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Here you can see the data we have inserted into our Azure Cosmos DB.</p>
<h2 id="heading-publish-the-function-app-to-azure"><strong>Publish the Function app to Azure</strong></h2>
<p>We have successfully created the Function app, but it is still running in the localhost. Let’s publish the app to make it available globally.</p>
<p>Right-click on the <code>FAQFunctionApp</code> project and select Publish. Select the Publish target as Azure.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/07/DeploytoAZ_1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Select the specific target as “Azure Function App (windows)”.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/07/DeploytoAZ_2.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>In the next window, click on the “Create a new Azure Function…” button. A new Function App window will open. Refer to the image as shown below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/07/DeploytoAZ_3.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>You can fill in the details as indicated below:</p>
<ul>
<li><strong>Name:</strong> A globally unique name for your function app.</li>
<li><strong>Subscription</strong>: Select your Azure subscription name from the drop-down.</li>
<li><strong>Resource Group</strong>: Select an existing Resource Group or create a new one.</li>
<li><strong>Plan Type</strong>: Select Consumption. It will make sure that you pay only for executions of your functions app.</li>
<li><strong>Location:</strong> Select a location for your function.</li>
<li><strong>Azure Storage</strong>: Keep the default value.</li>
</ul>
<p>Click on the “Create” button to create the Function App and return to the previous window. Make sure the option “Run from package file” is checked. Click on the Finish button.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/07/DeploytoAZ_4.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Now you are at the Publish page. Click on the “Manage Azure App Service Settings” button.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/07/ManageAZappSetting.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>You will see a “Application Settings” window as shown below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/07/SetConnString.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>At this point, we will configure the Remote value for the “DBConnectionString” key. This value is used when the app is deployed on Azure. Since the key for Local and Remote environment is the same in our case, click on the “Insert value from Local” button to copy the value from the Local field to the Remote field. Click on the OK button.</p>
<p>You are navigated back to the Publish page. We are done with all the configurations. Click on the Publish button to publish your Azure function app. After the app is published, get the site URL value, append <code>/api/covidFAQ</code> to it and open it in the browser. You can see the output as shown below.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/07/ExecuteGlobally.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>This is the same dataset that we got while running the app locally. This proves that our serverless Azure function is deployed and able to access the Azure Cosmos DB successfully.</p>
<h2 id="heading-enable-cors-for-the-azure-app-service"><strong>Enable CORS for the Azure app service</strong></h2>
<p>We will use the Function app in a Blazor UI project. To allow the Blazor app to access the Azure Function, we need to enable CORS for the Azure app service.</p>
<p>Open the Azure portal. Navigate to “All resources”. Here, you can see the App service which we have created while Publishing the app the in previous section. Click on the resource to navigate to the resource page. Click on CORS on the left navigation. A CORS details pane will open.</p>
<p>Now we have two options here:</p>
<ol>
<li>Enter the specific origin URL to allow them to make cross-origin calls.</li>
<li>Remove all origin URL from the list, and use “*” wildcard to allow all the URL to make cross-origin calls.</li>
</ol>
<p>We will use the second option for our app. Remove all the previously listed URL and enter a single entry as “*” wildcard. Click on the Save button at the top. Refer to the image shown below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/07/AZFuncCors.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-create-the-blazor-web-assembly-project"><strong>Create the Blazor Web assembly project</strong></h2>
<p>Open Visual Studio 2019, click on “Create a new project”. Select “Blazor App” and click on the “Next” button. Refer to the image shown below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/07/CreateBlazorProj_1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>On the “Configure your new project” window, put the project name as <code>FAQUIApp</code> and click on the “Create” button as shown in the image below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/07/CreateBlazorProj_2.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>On the “Create a new Blazor app” window, select the “Blazor WebAssmebly App” template. Click on the Create button to create the project. Refer to the image shown below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/07/CreateBlazorProj_3.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>To create a new razor component, right-click on the Pages folder, select Add &gt;&gt;Razor Component.An “Add New Item” dialog box will open, put the name of your component as <code>CovidFAQ.razor</code> and click on the Add button. Refer to the image shown below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/07/CreateRazorComp.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Open <code>[CovidFAQ.razor](https://github.com/AnkitSharma-007/azure-serverless-with-blazor/blob/master/FAQUIApp/FAQUIApp/Pages/CovidFAQ.razor)</code> and put the following code into it.</p>
<pre><code>@page <span class="hljs-string">"/covidfaq"</span>
@inject HttpClient Http

&lt;div <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"d-flex justify-content-center"</span>&gt;
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"../Images/COVID_banner.jpg"</span> <span class="hljs-attr">alt</span>=<span class="hljs-string">"Image"</span> <span class="hljs-attr">style</span>=<span class="hljs-string">"width:80%; height:300px"</span> /&gt;</span></span>
&lt;/div&gt;
<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">br</span> /&gt;</span></span>
<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"d-flex justify-content-center"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Frequently asked Questions on Covid-19<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">hr</span> /&gt;</span></span>

@<span class="hljs-keyword">if</span> (questionList == <span class="hljs-literal">null</span>)
{
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">em</span>&gt;</span>Loading...<span class="hljs-tag">&lt;/<span class="hljs-name">em</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></span>
}
<span class="hljs-keyword">else</span>
{
    @foreach (<span class="hljs-keyword">var</span> question <span class="hljs-keyword">in</span> questionList)
    {
        <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"card"</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">h3</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"card-header"</span>&gt;</span>
                @question.Question
            <span class="hljs-tag">&lt;/<span class="hljs-name">h3</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"card-body"</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"card-text"</span>&gt;</span>@question.Answer<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
        <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">br</span> /&gt;</span></span>
    }
}

@code {

    private FAQ[] questionList;

    protected override <span class="hljs-keyword">async</span> Task OnInitializedAsync()
    {
        questionList = <span class="hljs-keyword">await</span> Http.GetFromJsonAsync&lt;FAQ[]&gt;(<span class="hljs-string">"https://faqfunctionapp20200611160123.azurewebsites.net/api/covidFAQ"</span>);
    }

    public <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">FAQ</span>
    </span>{
        public string Id { get; set; }
        public string Question { get; set; }
        public string Answer { get; set; }
    }
}
</code></pre><p>In the <code>@code</code> section, we have created a class called FAQ. The structure of this class is the same as that of the FAQ class we created earlier in the Azure function app<strong>.</strong> Inside the <code>OnInitializedAsync</code> method, we are hitting the API endpoint of our function app. The data returned from the API will be stored in a variable called <code>questionList</code> which is an array of type <code>FAQ</code>.</p>
<p>In the HTML section of the page, we have set a banner image at the top of the page. The image is available in the <code>/wwwroot/Images</code> folder. We will use a foreach loop to iterate over the <code>questionList</code> array and create a bootstrap card to display the question and answer.</p>
<h2 id="heading-adding-link-to-navigation-menu"><strong>Adding Link to Navigation menu</strong></h2>
<p>The last step is to add the link of our CovidFAQ component in the navigation menu. Open <code>[/Shared/NavMenu.razor](https://github.com/AnkitSharma-007/azure-serverless-with-blazor/blob/master/FAQUIApp/FAQUIApp/Shared/NavMenu.razor#L15-L19)</code> file and add the following code into it.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"nav-item px-3"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">NavLink</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"nav-link"</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"covidfaq"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"oi oi-plus"</span> <span class="hljs-attr">aria-hidden</span>=<span class="hljs-string">"true"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span> Covid FAQ
  <span class="hljs-tag">&lt;/<span class="hljs-name">NavLink</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
</code></pre>
<p>Remove the navigation links for Counter and Fetch-data components as they are not required for this application.</p>
<h2 id="heading-execution-demo"><strong>Execution Demo</strong></h2>
<p>Press F5 to launch the app. Click on the Covid FAQ button on the nav menu on the left. You can see all the questions and answers in a beautiful card layout as shown below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/07/BlazorExecution.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>You can also check the live app at <a target="_blank" href="https://covid19-faq.azurewebsites.net/">https://covid19-faq.azurewebsites.net/</a></p>
<h2 id="heading-summary"><strong>Summary</strong></h2>
<p>In this article, we learned about serverless and its advantage over the traditional 3-tier web architecture. We also learned how the Azure function fits in serverless web architecture. </p>
<p>To demonstrate the practical implementation of these concepts, we have created a Covid-19 FAQ app using the Blazor web assembly and Azure serverless. The questions and answers are displayed in the card layout using Bootstrap. </p>
<p>We have used the Azure cosmos DB as the primary database to store the questions and answers for our FAQ app. An Azure function is used to fetch data from the cosmos DB. We deployed the function app on Azure to make it available globally via an API endpoint.</p>
<h2 id="heading-see-also"><strong>See Also</strong></h2>
<ul>
<li><a target="_blank" href="https://ankitsharmablogs.com/optical-character-reader-using-blazor-and-computer-vision/">Optical Character Reader Using Blazor And Computer Vision</a></li>
<li><a target="_blank" href="https://ankitsharmablogs.com/multi-language-translator-using-blazor-and-azure-cognitive-services/">Multi-Language Translator Using Blazor And Azure Cognitive Services</a></li>
<li><a target="_blank" href="https://ankitsharmablogs.com/facebook-authentication-and-authorization-in-server-side-blazor-app/">Facebook Authentication And Authorization In Server-Side Blazor App</a></li>
<li><a target="_blank" href="https://ankitsharmablogs.com/continuous-deployment-for-angular-app-using-heroku-and-github/">Continuous Deployment For Angular App Using Heroku And GitHub</a></li>
<li><a target="_blank" href="https://ankitsharmablogs.com/google-authentication-and-authorization-in-server-side-blazor-app/">Google Authentication And Authorization In Server-Side Blazor App</a></li>
<li><a target="_blank" href="https://ankitsharmablogs.com/blazor-crud-using-google-cloud-firestore/">Blazor CRUD Using Google Cloud Firestore</a></li>
</ul>
<p>If you like the article, share with you friends. You can also connect with me on <a target="_blank" href="https://twitter.com/ankitsharma_007">Twitter</a> and <a target="_blank" href="https://www.linkedin.com/in/ankitsharma-007/">LinkedIn</a>.</p>
<p>Originally published at <a target="_blank" href="https://ankitsharmablogs.com/">https://ankitsharmablogs.com/</a></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Create a Multi-Language Translator Using Blazor and Azure Cognitive Services ]]>
                </title>
                <description>
                    <![CDATA[ By Ankit Sharma Introduction In this article, we will create a multilanguage translator using Blazor and the Translate Text Azure Cognitive Service.  This translator will be able to translate between all the languages supported by the Translate Text ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-create-a-multi-language-translator-using-blazor-and-azure-cognitive-services/</link>
                <guid isPermaLink="false">66d45da23dce891ac3a967ae</guid>
                
                    <category>
                        <![CDATA[ Aspnetcore ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Azure ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Blazor ]]>
                    </category>
                
                    <category>
                        <![CDATA[ translation ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Mon, 09 Mar 2020 14:14:00 +0000</pubDate>
                <media:content url="https://cdn-media-2.freecodecamp.org/w1280/5f9c9c3b740569d1a4ca30de.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Ankit Sharma</p>
<h2 id="heading-introduction">Introduction</h2>
<p>In this article, we will create a multilanguage translator using Blazor and the Translate Text Azure Cognitive Service. </p>
<p>This translator will be able to translate between all the languages supported by the Translate Text API. Currently, the Translate Text API supports more than 60 languages for translation. </p>
<p>The application will accept the text to translate and the target language as the input and returns the translated text and the detected language for the input text as the output.</p>
<p>Take a look at the output shown below.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/BlazorTranslator.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-prerequisites">Prerequisites</h2>
<ul>
<li>Install the latest .NET Core 3.1 SDK from <a target="_blank" href="https://dotnet.microsoft.com/download/dotnet-core/3.1">https://dotnet.microsoft.com/download/dotnet-core/3.1</a></li>
<li>Install the latest version of Visual Studio 2019 from <a target="_blank" href="https://visualstudio.microsoft.com/downloads/">https://visualstudio.microsoft.com/downloads/</a></li>
<li>An Azure subscription account. You can create a free Azure account at <a target="_blank" href="https://azure.microsoft.com/en-in/free/">https://azure.microsoft.com/en-in/free/</a></li>
</ul>
<h2 id="heading-source-code">Source Code</h2>
<p>You can get the source code from <a target="_blank" href="https://github.com/AnkitSharma-007/Blazor-Translator-Azure-Cognitive-Services">GitHub</a>.</p>
<h2 id="heading-create-the-azure-translator-text-cognitive-services-resource">Create the Azure Translator Text Cognitive Services resource</h2>
<p>Log in to the Azure portal and search for the cognitive services in the search bar and click on the result. Refer to the image shown below.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/CreateTextCogServ-1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>On the next screen, click on the <code>Add</code> button. It will open the cognitive services marketplace page. Search for the <code>Translator Text</code> in the search bar and click on the search result. It will open the Translator Text API page. Click on the <code>Create</code> button to create a new Translator Text resource. Refer to the image shown below.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/SelectTranslatorTextCogServ.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>On the <code>Create</code> page, fill in the details as indicated below.</p>
<ul>
<li>Name: Give a unique name for your resource.</li>
<li>Subscription: Select the subscription type from the dropdown.</li>
<li>Pricing tier: Select the pricing tier as per your choice.</li>
<li>Resource group: Select an existing resource group or create a new one.</li>
</ul>
<p>Click on the <code>Create</code> button. Refer to the image shown below.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/ConfigureTranslatorTextCogServ.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>After your resource is successfully deployed, click on the “Go to resource” button. You can see the Key and the endpoint for the newly created Translator Text resource. Refer to the image shown below.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/TextCogServKey.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Make a note of the key, as we will be using this in the latter part of this article to request the translations from the Translator Text API. The values are masked here for privacy.</p>
<h2 id="heading-create-a-server-side-blazor-application">Create a Server-Side Blazor Application</h2>
<p>Open Visual Studio 2019 and click on “Create a new project”. Select “Blazor App” and click on the “Next” button. Refer to the image shown below.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/CreateProject-1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>On the next window, put the project name as <code>BlazorTranslator</code> and click on the “Create” button. The next window will ask you to select the type of Blazor app. Select <code>Blazor Server App</code> and click on the Create button to create a new server-side Blazor application. Refer to the image shown below.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/BlazorTemplate-1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-creating-the-models">Creating the Models</h2>
<p>Right-click on <code>BlazorTranslator</code> project and select Add &gt;&gt; New Folder. Name the folder as Models. Again, right-click on the Models folder and select Add &gt;&gt; Class to add a new class file. Put the name of your class as <code>LanguageDetails.cs</code> and click Add.</p>
<p>Open <code>[LanguageDetails.cs](https://github.com/AnkitSharma-007/Blazor-Translator-Azure-Cognitive-Services/blob/master/BlazorTranslator/Models/LanguageDetails.cs)</code> and put the following code inside it.</p>
<pre><code class="lang-c#"><span class="hljs-keyword">namespace</span> <span class="hljs-title">BlazorTranslator.Models</span>
{
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">LanguageDetails</span>
    {
        <span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> Name { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
        <span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> NativeName { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
        <span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> Dir { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
    }
}
</code></pre>
<p>Similarly, add a new class file <code>[TextResult.cs](https://github.com/AnkitSharma-007/Blazor-Translator-Azure-Cognitive-Services/blob/master/BlazorTranslator/Models/TextResult.cs)</code> and put the following code inside it.</p>
<pre><code class="lang-c#"><span class="hljs-keyword">using</span> System;
<span class="hljs-keyword">namespace</span> <span class="hljs-title">BlazorTranslator.Models</span>
{
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">TextResult</span>
    {
        <span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> Text { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
        <span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> Script { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
    }
}
</code></pre>
<p>Add a new class file <code>[Translation.cs](https://github.com/AnkitSharma-007/Blazor-Translator-Azure-Cognitive-Services/blob/master/BlazorTranslator/Models/Translation.cs)</code> and put the following code inside it.</p>
<pre><code class="lang-c#"><span class="hljs-keyword">namespace</span> <span class="hljs-title">BlazorTranslator.Models</span>
{
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Translation</span>
    {
        <span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> Text { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
        <span class="hljs-keyword">public</span> TextResult Transliteration { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
        <span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> To { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
    }
}
</code></pre>
<p>Create a class file <code>[DetectedLanguage.cs](https://github.com/AnkitSharma-007/Blazor-Translator-Azure-Cognitive-Services/blob/master/BlazorTranslator/Models/DetectedLanguage.cs)</code> and put the following code inside it.</p>
<pre><code class="lang-c#"><span class="hljs-keyword">namespace</span> <span class="hljs-title">BlazorTranslator.Models</span>
{
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">DetectedLanguage</span>
    {
        <span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> Language { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
        <span class="hljs-keyword">public</span> <span class="hljs-keyword">float</span> Score { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
    }
}
</code></pre>
<p>Create a class file <code>[TranslationResult.cs](https://github.com/AnkitSharma-007/Blazor-Translator-Azure-Cognitive-Services/blob/master/BlazorTranslator/Models/TranslationResult.cs)</code> and put the following code inside it.</p>
<pre><code class="lang-c#"><span class="hljs-keyword">namespace</span> <span class="hljs-title">BlazorTranslator.Models</span>
{
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">TranslationResult</span>
    {
        <span class="hljs-keyword">public</span> DetectedLanguage DetectedLanguage { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
        <span class="hljs-keyword">public</span> TextResult SourceText { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
        <span class="hljs-keyword">public</span> Translation[] Translations { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
    }
}
</code></pre>
<p>Finally, create the class file <code>[AvailableLanguage.cs](https://github.com/AnkitSharma-007/Blazor-Translator-Azure-Cognitive-Services/blob/master/BlazorTranslator/Models/AvailableLanguage.cs)</code> and put the following code inside it.</p>
<pre><code class="lang-c#"><span class="hljs-keyword">using</span> System.Collections.Generic;

<span class="hljs-keyword">namespace</span> <span class="hljs-title">BlazorTranslator.Models</span>
{
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">AvailableLanguage</span>
    {
      <span class="hljs-keyword">public</span> Dictionary&lt;<span class="hljs-keyword">string</span>, LanguageDetails&gt; Translation { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
    }
}
</code></pre>
<h2 id="heading-create-the-translation-service">Create the Translation service</h2>
<p>Right-click on the <code>BlazorTranslator/Data</code> folder and select Add &gt;&gt; Class to add a new class file. Put the name of the file as <code>TranslationService.cs</code> and click on Add. Open <code>[TranslationService.cs](https://github.com/AnkitSharma-007/Blazor-Translator-Azure-Cognitive-Services/blob/master/BlazorTranslator/Data/TranslationService.cs)</code> file and put the following code inside it.</p>
<pre><code class="lang-c#"><span class="hljs-keyword">using</span> BlazorTranslator.Models;
<span class="hljs-keyword">using</span> Newtonsoft.Json;
<span class="hljs-keyword">using</span> System;
<span class="hljs-keyword">using</span> System.Net.Http;
<span class="hljs-keyword">using</span> System.Text;
<span class="hljs-keyword">using</span> System.Threading.Tasks;

<span class="hljs-keyword">namespace</span> <span class="hljs-title">BlazorTranslator.Data</span>
{
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">TranslationService</span>
    {
        <span class="hljs-keyword">public</span> <span class="hljs-keyword">async</span> Task&lt;TranslationResult[]&gt; GetTranslatation(<span class="hljs-keyword">string</span> textToTranslate, <span class="hljs-keyword">string</span> targetLanguage)
        {
            <span class="hljs-keyword">string</span> subscriptionKey = <span class="hljs-string">"af19d996a3cb4a70a808567aad5bc41a"</span>;
            <span class="hljs-keyword">string</span> apiEndpoint = <span class="hljs-string">"https://api.cognitive.microsofttranslator.com/"</span>;
            <span class="hljs-keyword">string</span> route = <span class="hljs-string">$"/translate?api-version=3.0&amp;to=<span class="hljs-subst">{targetLanguage}</span>"</span>;
            <span class="hljs-keyword">string</span> requestUri = apiEndpoint + route;
            TranslationResult[] translationResult = <span class="hljs-keyword">await</span> TranslateText(subscriptionKey, requestUri, textToTranslate);
            <span class="hljs-keyword">return</span> translationResult;
        }

        <span class="hljs-keyword">async</span> Task&lt;TranslationResult[]&gt; TranslateText(<span class="hljs-keyword">string</span> subscriptionKey, <span class="hljs-keyword">string</span> requestUri, <span class="hljs-keyword">string</span> inputText)
        {
            <span class="hljs-keyword">object</span>[] body = <span class="hljs-keyword">new</span> <span class="hljs-keyword">object</span>[] { <span class="hljs-keyword">new</span> { Text = inputText } };
            <span class="hljs-keyword">var</span> requestBody = JsonConvert.SerializeObject(body);

            <span class="hljs-keyword">using</span> (<span class="hljs-keyword">var</span> client = <span class="hljs-keyword">new</span> HttpClient())
            <span class="hljs-keyword">using</span> (<span class="hljs-keyword">var</span> request = <span class="hljs-keyword">new</span> HttpRequestMessage())
            {
                request.Method = HttpMethod.Post;
                request.RequestUri = <span class="hljs-keyword">new</span> Uri(requestUri);
                request.Content = <span class="hljs-keyword">new</span> StringContent(requestBody, Encoding.UTF8, <span class="hljs-string">"application/json"</span>);
                request.Headers.Add(<span class="hljs-string">"Ocp-Apim-Subscription-Key"</span>, subscriptionKey);

                HttpResponseMessage response = <span class="hljs-keyword">await</span> client.SendAsync(request).ConfigureAwait(<span class="hljs-literal">false</span>);
                <span class="hljs-keyword">string</span> result = <span class="hljs-keyword">await</span> response.Content.ReadAsStringAsync();
                TranslationResult[] deserializedOutput = JsonConvert.DeserializeObject&lt;TranslationResult[]&gt;(result);

                <span class="hljs-keyword">return</span> deserializedOutput;
            }
        }

        <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">async</span> Task&lt;AvailableLanguage&gt; <span class="hljs-title">GetAvailableLanguages</span>(<span class="hljs-params"></span>)</span>
        {
            <span class="hljs-keyword">string</span> endpoint = <span class="hljs-string">"https://api.cognitive.microsofttranslator.com/languages?api-version=3.0&amp;scope=translation"</span>;
            <span class="hljs-keyword">var</span> client = <span class="hljs-keyword">new</span> HttpClient();
            <span class="hljs-keyword">using</span> (<span class="hljs-keyword">var</span> request = <span class="hljs-keyword">new</span> HttpRequestMessage())
            {
                request.Method = HttpMethod.Get;
                request.RequestUri = <span class="hljs-keyword">new</span> Uri(endpoint);
                <span class="hljs-keyword">var</span> response = <span class="hljs-keyword">await</span> client.SendAsync(request).ConfigureAwait(<span class="hljs-literal">false</span>);
                <span class="hljs-keyword">string</span> result = <span class="hljs-keyword">await</span> response.Content.ReadAsStringAsync();

                AvailableLanguage deserializedOutput = JsonConvert.DeserializeObject&lt;AvailableLanguage&gt;(result);

                <span class="hljs-keyword">return</span> deserializedOutput;
            }
        }
    }
}
</code></pre>
<p>We have defined a <code>GetTranslatation</code> method which will accept two parameters – the text to translate and the target language. We will set the subscription key for the Azure Translator Text cognitive service and define a variable for the global endpoint for Translator Text. The request URL contains the API endpoint along with the target language.</p>
<p>Inside the <code>TranslateText</code> method, we will create a new <code>HttpRequestMessage</code>. This HTTP request is a Post request. We will pass the subscription key in the header of the request. The Translator Text API returns a JSON object, which will be deserialized to an array of type <code>TranslationResult</code>. The output contains the translated text as well as the language detected for the input text.</p>
<p>The <code>GetAvailableLanguages</code> method will return the list of all the language supported by the Translate Text API. We will set the request URI and create a <code>HttpRequestMessage</code> which will be a Get request. This request URL will return a JSON object which will be deserialized to an object of type <code>AvailableLanguage</code>.</p>
<h2 id="heading-configuring-the-service">Configuring the Service</h2>
<p>To make the service available to the components we need to configure it on the server-side app. Open the <code>Startup.cs</code> file. Add the following line inside the <code>[ConfigureServices](https://github.com/AnkitSharma-007/Blazor-Translator-Azure-Cognitive-Services/blob/master/BlazorTranslator/Startup.cs#L28)</code> method of Startup class.</p>
<pre><code>services.AddSingleton&lt;TranslationService&gt;();
</code></pre><h2 id="heading-creating-the-blazor-ui-component">Creating the Blazor UI Component</h2>
<p>We will add the Razor page in <code>BlazorTranslator/Pages</code> folder. By default, we have “Counter” and “Fetch Data” pages provided in our application. These default pages will not affect our application but for the sake of this tutorial, we will delete fetchdata and counter pages from <code>BlazorTranslator/Pages</code> folder.</p>
<p>Right-click on <code>BlazorTranslator/Pages</code> folder and then select Add &gt;&gt; New Item. An “Add New Item” dialog box will open, select “Visual C#” from the left panel, then select “Razor Component” from the templates panel, put the name as <code>Translator.razor</code>. Click <code>Add</code>. Refer to the image shown below.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/AddRazorComp-1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Open the <code>[Translator.razor](https://github.com/AnkitSharma-007/Blazor-Translator-Azure-Cognitive-Services/blob/master/BlazorTranslator/Pages/Translator.razor)</code> file and add the following code at the top.</p>
<pre><code>@page <span class="hljs-string">"/translator"</span>
@using BlazorTranslator.Models
@using BlazorTranslator.Data
@inject TranslationService translationService
</code></pre><p>We have defined the route for this component. We are also injecting the <code>TranslationService</code> in this component.</p>
<p>Now we will add the following HTML code in this file.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">h3</span>&gt;</span>Multilanguage translator using Microsoft Translator API Cognitive Service<span class="hljs-tag">&lt;/<span class="hljs-name">h3</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">hr</span> /&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"container"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"row"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"col-md-6"</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">select</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-control"</span> @<span class="hljs-attr">bind</span>=<span class="hljs-string">"inputLanguage"</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">option</span> <span class="hljs-attr">value</span>=<span class="hljs-string">""</span>&gt;</span>-- Select input language --<span class="hljs-tag">&lt;/<span class="hljs-name">option</span>&gt;</span>
                @foreach (KeyValuePair<span class="hljs-tag">&lt;<span class="hljs-name">string,</span> <span class="hljs-attr">LanguageDetails</span>&gt;</span> lang in LanguageList)
                {
                    <span class="hljs-tag">&lt;<span class="hljs-name">option</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"@lang.Key"</span>&gt;</span>@lang.Value.Name<span class="hljs-tag">&lt;/<span class="hljs-name">option</span>&gt;</span>
                }
            <span class="hljs-tag">&lt;/<span class="hljs-name">select</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">textarea</span> <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Enter text to translate"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-control translation-box"</span> <span class="hljs-attr">rows</span>=<span class="hljs-string">"5"</span> @<span class="hljs-attr">bind</span>=<span class="hljs-string">"@inputText"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">textarea</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"col-md-6"</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">select</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-control"</span> @<span class="hljs-attr">onchange</span>=<span class="hljs-string">"SelectLanguage"</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">option</span> <span class="hljs-attr">value</span>=<span class="hljs-string">""</span>&gt;</span>-- Select target language --<span class="hljs-tag">&lt;/<span class="hljs-name">option</span>&gt;</span>
                @foreach (KeyValuePair<span class="hljs-tag">&lt;<span class="hljs-name">string,</span> <span class="hljs-attr">LanguageDetails</span>&gt;</span> lang in LanguageList)
                {
                    <span class="hljs-tag">&lt;<span class="hljs-name">option</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"@lang.Key"</span>&gt;</span>@lang.Value.Name<span class="hljs-tag">&lt;/<span class="hljs-name">option</span>&gt;</span>
                }
            <span class="hljs-tag">&lt;/<span class="hljs-name">select</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">textarea</span> <span class="hljs-attr">disabled</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-control translation-box"</span> <span class="hljs-attr">rows</span>=<span class="hljs-string">"5"</span>&gt;</span>@outputText<span class="hljs-tag">&lt;/<span class="hljs-name">textarea</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"text-center"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"btn btn-primary btn-lg"</span> @<span class="hljs-attr">onclick</span>=<span class="hljs-string">"Translate"</span>&gt;</span>Translate<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<p>We have defined two dropdown lists, one each for input language and the target language. The Azure Translate Text API will detect the input language and we will use that value to populate the dropdown for input language. We have also defined two text areas for the input and the translated text.</p>
<p>Finally, add the following code in the <code>@code</code> section of the page.</p>
<pre><code class="lang-c#">@code {
    <span class="hljs-keyword">private</span> TranslationResult[] translations;
    <span class="hljs-keyword">private</span> AvailableLanguage availableLanguages;

    <span class="hljs-keyword">private</span> <span class="hljs-keyword">string</span> outputLanguage { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">string</span> inputLanguage { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }

    <span class="hljs-keyword">string</span> inputText { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
    <span class="hljs-keyword">string</span> outputText { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }

    <span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-title">Dictionary</span>&lt;<span class="hljs-title">string</span>, <span class="hljs-title">LanguageDetails</span>&gt; LanguageList</span> = <span class="hljs-keyword">new</span> Dictionary&lt;<span class="hljs-keyword">string</span>, LanguageDetails&gt;();

    <span class="hljs-function"><span class="hljs-keyword">protected</span> <span class="hljs-keyword">override</span> <span class="hljs-keyword">async</span> Task <span class="hljs-title">OnInitializedAsync</span>(<span class="hljs-params"></span>)</span>
    {
        availableLanguages = <span class="hljs-keyword">await</span> translationService.GetAvailableLanguages();
        LanguageList = availableLanguages.Translation;
    }

    <span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-keyword">void</span> <span class="hljs-title">SelectLanguage</span>(<span class="hljs-params">ChangeEventArgs langEvent</span>)</span>
    {
        <span class="hljs-keyword">this</span>.outputLanguage = langEvent.Value.ToString();
    }

    <span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-keyword">async</span> Task <span class="hljs-title">Translate</span>(<span class="hljs-params"></span>)</span>
    {
        <span class="hljs-keyword">if</span> (!<span class="hljs-keyword">string</span>.IsNullOrEmpty(outputLanguage))
        {
            translations = <span class="hljs-keyword">await</span> translationService.GetTranslatation(<span class="hljs-keyword">this</span>.inputText, <span class="hljs-keyword">this</span>.outputLanguage);
            outputText = translations[<span class="hljs-number">0</span>].Translations[<span class="hljs-number">0</span>].Text;
            inputLanguage = translations[<span class="hljs-number">0</span>].DetectedLanguage.Language;
        }
    }
}
</code></pre>
<p>We are invoking the <code>GetAvailableLanguages</code> method from our service inside the <code>OnInitializedAsync</code>. This <code>OnInitializedAsync</code> is a lifecycle method that will be invoked upon component initialization. This will make sure that the language dropdown will be populated as the page loads.</p>
<p>The <code>SelectLanguage</code> method will set the <code>outputLanguage</code> for the translation. The Translate method will invoke the <code>GetTranslatation</code> method from the service. We will set the <code>outputText</code> and the language detected for the <code>inputLanguage</code> as returned from the service.</p>
<h2 id="heading-add-styling-for-the-translator-component">Add styling for the Translator component</h2>
<p>Navigate to <code>[BlazorTranslator\wwwroot\css\site.css](https://github.com/AnkitSharma-007/Blazor-Translator-Azure-Cognitive-Services/blob/master/BlazorTranslator/wwwroot/css/site.css#L185-L187)</code> file and put the following style definition inside it.</p>
<pre><code class="lang-css"><span class="hljs-selector-class">.translation-box</span> {
    <span class="hljs-attribute">margin</span>: <span class="hljs-number">15px</span> <span class="hljs-number">0px</span>;
}
</code></pre>
<h2 id="heading-adding-link-to-navigation-menu">Adding Link to Navigation menu</h2>
<p>The last step is to add the link of our Translator component in the navigation menu. Open <code>[BlazorTranslator/Shared/NavMenu.razor](https://github.com/AnkitSharma-007/Blazor-Translator-Azure-Cognitive-Services/blob/master/BlazorTranslator/Shared/NavMenu.razor#L15-L19)</code> file and add the following code into it.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"nav-item px-3"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">NavLink</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"nav-link"</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"translator"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"oi oi-list-rich"</span> <span class="hljs-attr">aria-hidden</span>=<span class="hljs-string">"true"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span> Translator
    <span class="hljs-tag">&lt;/<span class="hljs-name">NavLink</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
</code></pre>
<p>Remove the navigation links for Counter and Fetch-data components as they are not required for this application.</p>
<h2 id="heading-execution-demo">Execution Demo</h2>
<p>Press F5 to launch the application. Click on the Translator button on the nav menu in the left. You can perform the multilanguage translation as shown in the image below.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/BlazorTranslator-1.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-summary">Summary</h2>
<p>We have created a Translator Text Cognitive Services resource on Azure. We have used the Translator Text API to create a multilanguage translator using Blazor. This translator supports more than 60 languages for translation. We fetched the list of supported languages for translation from the global API endpoint for Translator Text.</p>
<p>Get the Source code from <a target="_blank" href="https://github.com/AnkitSharma-007/Blazor-Translator-Azure-Cognitive-Services">GitHub</a> and play around to get a better understanding.</p>
<h2 id="heading-see-also">See Also</h2>
<ul>
<li><a target="_blank" href="https://ankitsharmablogs.com/optical-character-reader-using-blazor-and-computer-vision/">Optical Character Reader Using Blazor And Computer Vision</a></li>
<li><a target="_blank" href="https://ankitsharmablogs.com/facebook-authentication-and-authorization-in-server-side-blazor-app/">Facebook Authentication And Authorization In Server-Side Blazor App</a></li>
<li><a target="_blank" href="https://ankitsharmablogs.com/google-authentication-and-authorization-in-server-side-blazor-app/">Google Authentication And Authorization In Server-Side Blazor App</a></li>
<li><a target="_blank" href="https://ankitsharmablogs.com/blazor-crud-using-google-cloud-firestore/">Blazor CRUD Using Google Cloud Firestore</a></li>
<li><a target="_blank" href="https://ankitsharmablogs.com/hosting-a-blazor-application-on-firebase/">Hosting A Blazor Application on Firebase</a></li>
<li><a target="_blank" href="https://ankitsharmablogs.com/localization-in-angular-using-i18n-tools/">Localization In Angular Using i18n Tools</a></li>
</ul>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Create an Optical Character Reader Using Blazor and Azure Computer Vision ]]>
                </title>
                <description>
                    <![CDATA[ By Ankit Sharma Introduction In this article, we will create an optical character recognition (OCR) application using Blazor and the Azure Computer Vision Cognitive Service.  Computer Vision is an AI service that analyzes content in images. We will u... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-create-an-optical-character-reader-using-blazor-and-azure-computer-vision/</link>
                <guid isPermaLink="false">66d45dae33b83c4378a517ba</guid>
                
                    <category>
                        <![CDATA[ Aspnetcore ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Azure ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Blazor ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Computer Vision ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Tue, 03 Mar 2020 18:48:00 +0000</pubDate>
                <media:content url="https://cdn-media-2.freecodecamp.org/w1280/5f9c9c4c740569d1a4ca3143.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Ankit Sharma</p>
<h2 id="heading-introduction">Introduction</h2>
<p>In this article, we will create an optical character recognition (OCR) application using Blazor and the Azure Computer Vision Cognitive Service. </p>
<p>Computer Vision is an AI service that analyzes content in images. We will use the OCR feature of Computer Vision to detect the printed text in an image. </p>
<p>The application will extract the text from the image and detects the language of the text. Currently, the OCR API supports 25 languages.</p>
<p>A demo of the application is shown below.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/BlazorComputerVision-1.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-prerequisites">Prerequisites</h2>
<ul>
<li>Install the latest .NET Core 3.1 SDK from <a target="_blank" href="https://dotnet.microsoft.com/download/dotnet-core/3.1">https://dotnet.microsoft.com/download/dotnet-core/3.1</a></li>
<li>Install the latest version of Visual Studio 2019 from <a target="_blank" href="https://visualstudio.microsoft.com/downloads/">https://visualstudio.microsoft.com/downloads/</a></li>
<li>An Azure subscription account. You can create a free Azure account  at <a target="_blank" href="https://azure.microsoft.com/en-in/free/">https://azure.microsoft.com/en-in/free/</a></li>
</ul>
<h2 id="heading-image-requirements">Image requirements</h2>
<p>The OCR API will work on images that meet the requirements as mentioned below:</p>
<ul>
<li>The format of the image must be JPEG, PNG, GIF, or BMP.</li>
<li>The size of the image must be between 50 x 50 and 4200 x 4200 pixels.</li>
<li>The image file size should be less than 4 MB.</li>
<li>The text in the image can be rotated by any multiple of 90 degrees plus a small angle of up to 40 degrees.</li>
</ul>
<h2 id="heading-source-code">Source Code</h2>
<p>You can get the source code from <a target="_blank" href="https://github.com/AnkitSharma-007/Blazor-Computer-Vision-Azure-Cognitive-Services">GitHub</a>.</p>
<h2 id="heading-create-the-azure-computer-vision-cognitive-service-resource">Create the Azure Computer Vision Cognitive Service resource</h2>
<p>Log in to the Azure portal and search for the cognitive services in the search bar and click on the result. Refer to the image shown below.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/CreateTextCogServ.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>On the next screen, click on the Add button. It will open the cognitive services marketplace page. </p>
<p>Search for the Computer Vision in the search bar and click on the search result. It will open the Computer Vision API page. Click on the Create button to create a new Computer Vision resource. Refer to the image shown below.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/SelectComputerVisionCogServ-1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>On the Create page, fill in the details as indicated below.</p>
<ul>
<li><strong>Name</strong>: Give a unique name for your resource.</li>
<li><strong>Subscription</strong>: Select the subscription type from the dropdown.</li>
<li><strong>Pricing tier</strong>: Select the pricing tier as per your choice.</li>
<li><strong>Resource group</strong>: Select an existing resource group or create a new one.</li>
</ul>
<p>Click on the Create button. Refer to the image shown below.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/BlazorConfigureComputerVisionCogServ.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>After your resource is successfully deployed, click on the “Go to resource” button. You can see the Key and the endpoint for the newly created Computer Vision resource. Refer to the image shown below.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/ComputerVisionCogServKey.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Make a note of the key and the endpoint. We will be using these in the latter part of this article to invoke the Computer Vision OCR API from the .NET Code. The values are masked here for privacy.</p>
<h2 id="heading-create-a-server-side-blazor-application">Create a Server-Side Blazor Application</h2>
<p>Open Visual Studio 2019, click on “Create a new project”. Select “Blazor App” and click on the “Next” button. Refer to the image shown below.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/CreateProject.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>On the next window, put the project name as <code>BlazorComputerVision</code> and click on the “Create” button. </p>
<p>The next window will ask you to select the type of Blazor app. Select <code>Blazor Server App</code> and click on the Create button to create a new server-side Blazor application. Refer to the image shown below.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/BlazorTemplate.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-installing-computer-vision-api-library">Installing Computer Vision API library</h2>
<p>We will install the Azure Computer Vision API library which will provide us with the models out of the box to handle the Computer Vision REST API response. </p>
<p>To install the package, navigate to Tools &gt;&gt; NuGet Package Manager &gt;&gt; Package Manager Console. It will open the Package Manager Console. Run the command as shown below.</p>
<pre><code>Install-Package Microsoft.Azure.CognitiveServices.Vision.ComputerVision -Version <span class="hljs-number">5.0</span><span class="hljs-number">.0</span>
</code></pre><p>You can learn more about this package at the <a target="_blank" href="https://www.nuget.org/packages/Microsoft.Azure.CognitiveServices.Vision.ComputerVision/">NuGet gallery</a>.</p>
<h2 id="heading-create-the-models">Create the Models</h2>
<p>Right-click on the <code>BlazorComputerVision</code> project and select Add &gt;&gt; New Folder. Name the folder as <code>Models</code>. Again, right-click on the <code>Models</code> folder and select Add &gt;&gt; Class to add a new class file. Put the name of your class as <code>LanguageDetails.cs</code> and click Add.</p>
<p>Open <code>[LanguageDetails.cs](https://github.com/AnkitSharma-007/Blazor-Computer-Vision-Azure-Cognitive-Services/blob/master/BlazorComputerVision/Models/LanguageDetails.cs)</code> and put the following code inside it.</p>
<pre><code class="lang-c#"><span class="hljs-keyword">namespace</span> <span class="hljs-title">BlazorComputerVision.Models</span>
{
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">LanguageDetails</span>
    {
        <span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> Name { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
        <span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> NativeName { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
        <span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> Dir { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
    }
}
</code></pre>
<p>Similarly, add a new class file <code>[AvailableLanguage.cs](https://github.com/AnkitSharma-007/Blazor-Computer-Vision-Azure-Cognitive-Services/blob/master/BlazorComputerVision/Models/AvailableLanguage.cs)</code> and put the following code inside it.</p>
<pre><code class="lang-c#"><span class="hljs-keyword">using</span> System.Collections.Generic;

<span class="hljs-keyword">namespace</span> <span class="hljs-title">BlazorComputerVision.Models</span>
{
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">AvailableLanguage</span>
    {
        <span class="hljs-keyword">public</span> Dictionary&lt;<span class="hljs-keyword">string</span>, LanguageDetails&gt; Translation { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
    }
}
</code></pre>
<p>Finally, we will add a class as DTO (Data Transfer Object) for sending data back to the client. Add a new class file <code>[OcrResultDTO.cs](https://github.com/AnkitSharma-007/Blazor-Computer-Vision-Azure-Cognitive-Services/blob/master/BlazorComputerVision/Models/OcrResultDTO.cs)</code> and put the following code inside it.</p>
<pre><code class="lang-c#"><span class="hljs-keyword">namespace</span> <span class="hljs-title">BlazorComputerVision.Models</span>
{
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">OcrResultDTO</span>
    {
        <span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> Language { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }

        <span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> DetectedText { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
    }
}
</code></pre>
<h2 id="heading-create-the-computer-vision-service">Create the Computer Vision Service</h2>
<p>Right-click on the <code>BlazorComputerVision/Data</code> folder and select Add &gt;&gt; Class to add a new class file. Put the name of the file as <code>ComputerVisionService.cs</code> and click on Add.</p>
<p>Open the <code>[ComputerVisionService.cs](https://github.com/AnkitSharma-007/Blazor-Computer-Vision-Azure-Cognitive-Services/blob/master/BlazorComputerVision/Data/ComputerVisionService.cs)</code> file and put the following code inside it.</p>
<pre><code class="lang-c#"><span class="hljs-keyword">using</span> BlazorComputerVision.Models;
<span class="hljs-keyword">using</span> Microsoft.Azure.CognitiveServices.Vision.ComputerVision.Models;
<span class="hljs-keyword">using</span> Newtonsoft.Json;
<span class="hljs-keyword">using</span> Newtonsoft.Json.Linq;
<span class="hljs-keyword">using</span> System;
<span class="hljs-keyword">using</span> System.Net.Http;
<span class="hljs-keyword">using</span> System.Net.Http.Headers;
<span class="hljs-keyword">using</span> System.Text;
<span class="hljs-keyword">using</span> System.Threading.Tasks;

<span class="hljs-keyword">namespace</span> <span class="hljs-title">BlazorComputerVision.Data</span>
{
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">ComputerVisionService</span>
    {
        <span class="hljs-keyword">static</span> <span class="hljs-keyword">string</span> subscriptionKey;
        <span class="hljs-keyword">static</span> <span class="hljs-keyword">string</span> endpoint;
        <span class="hljs-keyword">static</span> <span class="hljs-keyword">string</span> uriBase;

        <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">ComputerVisionService</span>(<span class="hljs-params"></span>)</span>
        {
            subscriptionKey = <span class="hljs-string">"b993f3afb4e04119bd8ed37171d4ec71"</span>;
            endpoint = <span class="hljs-string">"https://ankitocrdemo.cognitiveservices.azure.com/"</span>;
            uriBase = endpoint + <span class="hljs-string">"vision/v2.1/ocr"</span>;
        }

        <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">async</span> Task&lt;OcrResultDTO&gt; <span class="hljs-title">GetTextFromImage</span>(<span class="hljs-params"><span class="hljs-keyword">byte</span>[] imageFileBytes</span>)</span>
        {
            StringBuilder sb = <span class="hljs-keyword">new</span> StringBuilder();
            OcrResultDTO ocrResultDTO = <span class="hljs-keyword">new</span> OcrResultDTO();
            <span class="hljs-keyword">try</span>
            {
                <span class="hljs-keyword">string</span> JSONResult = <span class="hljs-keyword">await</span> ReadTextFromStream(imageFileBytes);

                OcrResult ocrResult = JsonConvert.DeserializeObject&lt;OcrResult&gt;(JSONResult);

                <span class="hljs-keyword">if</span> (!ocrResult.Language.Equals(<span class="hljs-string">"unk"</span>))
                {
                    <span class="hljs-keyword">foreach</span> (OcrLine ocrLine <span class="hljs-keyword">in</span> ocrResult.Regions[<span class="hljs-number">0</span>].Lines)
                    {
                        <span class="hljs-keyword">foreach</span> (OcrWord ocrWord <span class="hljs-keyword">in</span> ocrLine.Words)
                        {
                            sb.Append(ocrWord.Text);
                            sb.Append(<span class="hljs-string">' '</span>);
                        }
                        sb.AppendLine();
                    }
                }
                <span class="hljs-keyword">else</span>
                {
                    sb.Append(<span class="hljs-string">"This language is not supported."</span>);
                }
                ocrResultDTO.DetectedText = sb.ToString();
                ocrResultDTO.Language = ocrResult.Language;
                <span class="hljs-keyword">return</span> ocrResultDTO;
            }
            <span class="hljs-keyword">catch</span>
            {
                ocrResultDTO.DetectedText = <span class="hljs-string">"Error occurred. Try again"</span>;
                ocrResultDTO.Language = <span class="hljs-string">"unk"</span>;
                <span class="hljs-keyword">return</span> ocrResultDTO;
            }
        }

        <span class="hljs-function"><span class="hljs-keyword">static</span> <span class="hljs-keyword">async</span> Task&lt;<span class="hljs-keyword">string</span>&gt; <span class="hljs-title">ReadTextFromStream</span>(<span class="hljs-params"><span class="hljs-keyword">byte</span>[] byteData</span>)</span>
        {
            <span class="hljs-keyword">try</span>
            {
                HttpClient client = <span class="hljs-keyword">new</span> HttpClient();
                client.DefaultRequestHeaders.Add(<span class="hljs-string">"Ocp-Apim-Subscription-Key"</span>, subscriptionKey);
                <span class="hljs-keyword">string</span> requestParameters = <span class="hljs-string">"language=unk&amp;detectOrientation=true"</span>;
                <span class="hljs-keyword">string</span> uri = uriBase + <span class="hljs-string">"?"</span> + requestParameters;
                HttpResponseMessage response;

                <span class="hljs-keyword">using</span> (ByteArrayContent content = <span class="hljs-keyword">new</span> ByteArrayContent(byteData))
                {
                    content.Headers.ContentType = <span class="hljs-keyword">new</span> MediaTypeHeaderValue(<span class="hljs-string">"application/octet-stream"</span>);
                    response = <span class="hljs-keyword">await</span> client.PostAsync(uri, content);
                }

                <span class="hljs-keyword">string</span> contentString = <span class="hljs-keyword">await</span> response.Content.ReadAsStringAsync();
                <span class="hljs-keyword">string</span> result = JToken.Parse(contentString).ToString();
                <span class="hljs-keyword">return</span> result;
            }
            <span class="hljs-keyword">catch</span> (Exception e)
            {
                <span class="hljs-keyword">return</span> e.Message;
            }
        }

        <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">async</span> Task&lt;AvailableLanguage&gt; <span class="hljs-title">GetAvailableLanguages</span>(<span class="hljs-params"></span>)</span>
        {
            <span class="hljs-keyword">string</span> endpoint = <span class="hljs-string">"https://api.cognitive.microsofttranslator.com/languages?api-version=3.0&amp;scope=translation"</span>;
            <span class="hljs-keyword">var</span> client = <span class="hljs-keyword">new</span> HttpClient();
            <span class="hljs-keyword">using</span> (<span class="hljs-keyword">var</span> request = <span class="hljs-keyword">new</span> HttpRequestMessage())
            {
                request.Method = HttpMethod.Get;
                request.RequestUri = <span class="hljs-keyword">new</span> Uri(endpoint);
                <span class="hljs-keyword">var</span> response = <span class="hljs-keyword">await</span> client.SendAsync(request).ConfigureAwait(<span class="hljs-literal">false</span>);
                <span class="hljs-keyword">string</span> result = <span class="hljs-keyword">await</span> response.Content.ReadAsStringAsync();

                AvailableLanguage deserializedOutput = JsonConvert.DeserializeObject&lt;AvailableLanguage&gt;(result);

                <span class="hljs-keyword">return</span> deserializedOutput;
            }
        }
    }
}
</code></pre>
<p>In the constructor of the class, we have initialized the key and the endpoint URL for the OCR API.</p>
<p>Inside the <code>ReadTextFromStream</code> method, we will create a new <code>HttpRequestMessage</code>. This HTTP request is a Post request. We will pass the subscription key in the header of the request. The OCR API will return a JSON object having each word from the image as well as the detected language of the text.</p>
<p>The <code>GetTextFromImage</code> method will accept the image data as a byte array and returns an object of type <code>OcrResultDTO</code>. We will invoke the <code>ReadTextFromStream</code> method and deserialize the response into an object of type <code>OcrResult</code>. We will then form the sentence by iterating over the <code>OcrWord</code> object.</p>
<p>The <code>GetAvailableLanguages</code> method will return the list of all the language supported by the Translate Text API. We will set the request URI and create a <code>HttpRequestMessage</code> which will be a Get request. This request URL will return a JSON object which will be deserialized to an object of type <code>AvailableLanguage</code>.</p>
<h2 id="heading-why-do-we-need-to-fetch-the-list-of-supported-languages">Why do we need to fetch the list of supported languages?</h2>
<p>The OCR API returns the language code (e.g. en for English, de for German, etc.) of the detected language. But we cannot display the language code on the UI as it is not user-friendly. Therefore, we need a dictionary to look up the language name corresponding to the language code.</p>
<p>The Azure Computer Vision OCR API supports 25 languages. To know all the languages supported by OCR API see the list of <a target="_blank" href="https://docs.microsoft.com/en-us/azure/cognitive-services/computer-vision/language-support">supported languages</a>. </p>
<p>These languages are a subset of the languages supported by the Azure Translate Text API. Since there is no dedicated API endpoint to fetch the list of languages supported by OCR API, therefore, we are using the Translate Text API endpoint to fetch the list of languages. </p>
<p>We will create the language lookup dictionary using the JSON response from this API call and filter the result based on the language code returned by the OCR API.</p>
<h2 id="heading-install-blazorinputfile-nuget-package">Install BlazorInputFile NuGet package</h2>
<p><a target="_blank" href="https://www.nuget.org/packages/BlazorInputFile/">BlazorInputFile</a> is a file input component for Blazor applications. It provides the ability to upload single or multiple files to a Blazor app.</p>
<p>Open <code>[BlazorComputerVision.csproj](https://github.com/AnkitSharma-007/Blazor-Computer-Vision-Azure-Cognitive-Services/blob/master/BlazorComputerVision/BlazorComputerVision.csproj#L8)</code> file and add a dependency for the <code>BlazorInputFile</code> package as shown below:</p>
<pre><code class="lang-xhtml"><span class="hljs-tag">&lt;<span class="hljs-name">ItemGroup</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">PackageReference</span> <span class="hljs-attr">Include</span>=<span class="hljs-string">"BlazorInputFile"</span> <span class="hljs-attr">Version</span>=<span class="hljs-string">"0.1.0-preview-00002"</span> /&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">ItemGroup</span>&gt;</span>
</code></pre>
<p>Open <code>[BlazorComputerVision\Pages\_Host.cshtml](https://github.com/AnkitSharma-007/Blazor-Computer-Vision-Azure-Cognitive-Services/blob/master/BlazorComputerVision/Pages/_Host.cshtml#L17)</code> file and add the reference for the package’s JavaScript file by adding the following line in the <code>&lt;head&gt;</code> section.</p>
<pre><code class="lang-js">&lt;script src=<span class="hljs-string">"_content/BlazorInputFile/inputfile.js"</span>&gt;&lt;/script&gt;
</code></pre>
<p>Add the following line in the <code>[_Imports.razor](https://github.com/AnkitSharma-007/Blazor-Computer-Vision-Azure-Cognitive-Services/blob/master/BlazorComputerVision/_Imports.razor#L10)</code> file.</p>
<pre><code>@using BlazorInputFile
</code></pre><h2 id="heading-configuring-the-service"><strong>Configuring the Service</strong></h2>
<p>To make the service available to the components we need to configure it on the server-side app. Open the Startup.cs file. Add the following line inside the <code>[ConfigureServices](https://github.com/AnkitSharma-007/Blazor-Computer-Vision-Azure-Cognitive-Services/blob/master/BlazorComputerVision/Startup.cs#L31)</code> method of Startup class.</p>
<pre><code class="lang-c#"> services.AddSingleton&lt;ComputerVisionService&gt;();
</code></pre>
<h2 id="heading-creating-the-blazor-ui-component">Creating the Blazor UI Component</h2>
<p>We will add the Razor page in the <code>BlazorComputerVision/Pages</code> folder. By default, we have “Counter” and “Fetch Data” pages provided in our application. These default pages will not affect our application but for the sake of this tutorial, we will delete fetchdata and counter pages from <code>BlazorComputerVision/Pages</code> folder.</p>
<p>Right-click on the <code>BlazorComputerVision/Pages</code> folder and then select Add &gt;&gt; New Item. An “Add New Item” dialog box will open, select “Visual C#” from the left panel, then select “Razor Component” from the templates panel, put the name as <code>OCR.razor</code>. Click Add. Refer to the image shown below.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/BlazorOCRComponent.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>We will add a code-behind file for this razor page to keep the code and presentation separate. This will allow easy maintenance for the application.  </p>
<p>Right-click on the <code>BlazorComputerVision/Pages</code> folder and then select Add &gt;&gt; Class. Name the class as <code>OCR.razor.cs</code>. The Blazor framework is smart enough to tag this class file to the razor file. Refer to the image shown below.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/BlazorCodeBehind.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-blazor-ui-component-code-behind">Blazor UI component code behind</h2>
<p>Open the <code>[OCR.razor.cs](https://github.com/AnkitSharma-007/Blazor-Computer-Vision-Azure-Cognitive-Services/blob/master/BlazorComputerVision/Pages/OCR.razor.cs)</code> file and put the following code inside it.</p>
<pre><code class="lang-c#"><span class="hljs-keyword">using</span> Microsoft.AspNetCore.Components;
<span class="hljs-keyword">using</span> System;
<span class="hljs-keyword">using</span> System.Collections.Generic;
<span class="hljs-keyword">using</span> System.Linq;
<span class="hljs-keyword">using</span> System.Threading.Tasks;
<span class="hljs-keyword">using</span> System.IO;
<span class="hljs-keyword">using</span> BlazorComputerVision.Models;
<span class="hljs-keyword">using</span> BlazorInputFile;
<span class="hljs-keyword">using</span> BlazorComputerVision.Data;

<span class="hljs-keyword">namespace</span> <span class="hljs-title">BlazorComputerVision.Pages</span>
{
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">OCRModel</span> : <span class="hljs-title">ComponentBase</span>
    {
        [<span class="hljs-meta">Inject</span>]
        <span class="hljs-keyword">protected</span> ComputerVisionService computerVisionService { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }

        <span class="hljs-keyword">protected</span> <span class="hljs-keyword">string</span> DetectedTextLanguage;
        <span class="hljs-keyword">protected</span> <span class="hljs-keyword">string</span> imagePreview;
        <span class="hljs-keyword">protected</span> <span class="hljs-keyword">bool</span> loading = <span class="hljs-literal">false</span>;
        <span class="hljs-keyword">byte</span>[] imageFileBytes;

        <span class="hljs-keyword">const</span> <span class="hljs-keyword">string</span> DefaultStatus = <span class="hljs-string">"Maximum size allowed for the image is 4 MB"</span>;
        <span class="hljs-keyword">protected</span> <span class="hljs-keyword">string</span> status = DefaultStatus;

        <span class="hljs-keyword">protected</span> OcrResultDTO Result = <span class="hljs-keyword">new</span> OcrResultDTO();
        <span class="hljs-keyword">private</span> AvailableLanguage availableLanguages;
        <span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-title">Dictionary</span>&lt;<span class="hljs-title">string</span>, <span class="hljs-title">LanguageDetails</span>&gt; LanguageList</span> = <span class="hljs-keyword">new</span> Dictionary&lt;<span class="hljs-keyword">string</span>, LanguageDetails&gt;();
        <span class="hljs-keyword">const</span> <span class="hljs-keyword">int</span> MaxFileSize = <span class="hljs-number">4</span> * <span class="hljs-number">1024</span> * <span class="hljs-number">1024</span>; <span class="hljs-comment">// 4MB</span>

        <span class="hljs-function"><span class="hljs-keyword">protected</span> <span class="hljs-keyword">override</span> <span class="hljs-keyword">async</span> Task <span class="hljs-title">OnInitializedAsync</span>(<span class="hljs-params"></span>)</span>
        {
            availableLanguages = <span class="hljs-keyword">await</span> computerVisionService.GetAvailableLanguages();
            LanguageList = availableLanguages.Translation;
        }

        <span class="hljs-function"><span class="hljs-keyword">protected</span> <span class="hljs-keyword">async</span> Task <span class="hljs-title">ViewImage</span>(<span class="hljs-params">IFileListEntry[] files</span>)</span>
        {
            <span class="hljs-keyword">var</span> file = files.FirstOrDefault();
            <span class="hljs-keyword">if</span> (file == <span class="hljs-literal">null</span>)
            {
                <span class="hljs-keyword">return</span>;
            }
            <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (file.Size &gt; MaxFileSize)
            {
                status = <span class="hljs-string">$"The file size is <span class="hljs-subst">{file.Size}</span> bytes, this is more than the allowed limit of <span class="hljs-subst">{MaxFileSize}</span> bytes."</span>;
                <span class="hljs-keyword">return</span>;
            }
            <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (!file.Type.Contains(<span class="hljs-string">"image"</span>))
            {
                status = <span class="hljs-string">"Please uplaod a valid image file"</span>;
                <span class="hljs-keyword">return</span>;
            }
            <span class="hljs-keyword">else</span>
            {
                <span class="hljs-keyword">var</span> memoryStream = <span class="hljs-keyword">new</span> MemoryStream();
                <span class="hljs-keyword">await</span> file.Data.CopyToAsync(memoryStream);
                imageFileBytes = memoryStream.ToArray();
                <span class="hljs-keyword">string</span> base64String = Convert.ToBase64String(imageFileBytes, <span class="hljs-number">0</span>, imageFileBytes.Length);

                imagePreview = <span class="hljs-keyword">string</span>.Concat(<span class="hljs-string">"data:image/png;base64,"</span>, base64String);
                memoryStream.Flush();
                status = DefaultStatus;
            }
        }

        <span class="hljs-function"><span class="hljs-keyword">protected</span> <span class="hljs-keyword">private</span> <span class="hljs-keyword">async</span> Task <span class="hljs-title">GetText</span>(<span class="hljs-params"></span>)</span>
        {
            <span class="hljs-keyword">if</span> (imageFileBytes != <span class="hljs-literal">null</span>)
            {
                loading = <span class="hljs-literal">true</span>;
                Result = <span class="hljs-keyword">await</span> computerVisionService.GetTextFromImage(imageFileBytes);
                <span class="hljs-keyword">if</span> (LanguageList.ContainsKey(Result.Language))
                {
                    DetectedTextLanguage = LanguageList[Result.Language].Name;
                }
                <span class="hljs-keyword">else</span>
                {
                    DetectedTextLanguage = <span class="hljs-string">"Unknown"</span>;
                }
                loading = <span class="hljs-literal">false</span>;
            }
        }
    }
}
</code></pre>
<p>We are injecting the <code>ComputerVisionService</code> in this class.</p>
<p>The <code>OnInitializedAsync</code> is a Blazor lifecycle method which is invoked when the component is initialized. We are invoking the <code>GetAvailableLanguages</code> method from our service inside the <code>OnInitializedAsync</code> method. We will then initialize the variable LanguageList which is a dictionary to hold the details of available languages.</p>
<p>Inside the <code>ViewImage</code> method, we will check if the uploaded file is an image only and the size is less than 4 MB. We will transfer the uploaded image to the memory stream. We will then convert that memory stream to a byte array. </p>
<p>To set the image preview, we will convert the image from byte array to a base64 encoded string. The <code>GetText</code> method will invoke the <code>GetTextFromImage</code> method from the service and pass the image byte array as an argument. We will search for the language name from the dictionary based on the language code returned from the service. If no language code is available, we will set the language as unknown.</p>
<h2 id="heading-blazor-ui-component-template">Blazor UI component template</h2>
<p>Open the <code>[OCR.razor](https://github.com/AnkitSharma-007/Blazor-Computer-Vision-Azure-Cognitive-Services/blob/master/BlazorComputerVision/Pages/OCR.razor)</code> file and put the following code inside it.</p>
<pre><code class="lang-html">@page "/computer-vision-ocr"
@inherits OCRModel

<span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>Optical Character Recognition (OCR) Using Blazor and Azure Computer Vision Cognitive Service<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"row"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"col-md-5"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">textarea</span> <span class="hljs-attr">disabled</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-control"</span> <span class="hljs-attr">rows</span>=<span class="hljs-string">"10"</span> <span class="hljs-attr">cols</span>=<span class="hljs-string">"15"</span>&gt;</span>@Result.DetectedText<span class="hljs-tag">&lt;/<span class="hljs-name">textarea</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">hr</span> /&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"row"</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"col-sm-5"</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">label</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">strong</span>&gt;</span> Detected Language :<span class="hljs-tag">&lt;/<span class="hljs-name">strong</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"col-sm-6"</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">disabled</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-control"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"@DetectedTextLanguage"</span> /&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"col-md-5"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"image-container"</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"preview-image"</span> <span class="hljs-attr">src</span>=<span class="hljs-string">@imagePreview</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">InputFile</span> <span class="hljs-attr">OnChange</span>=<span class="hljs-string">"ViewImage"</span> /&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>@status<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">hr</span> /&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">disabled</span>=<span class="hljs-string">"@loading"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"btn btn-primary btn-lg"</span> @<span class="hljs-attr">onclick</span>=<span class="hljs-string">"GetText"</span>&gt;</span>
            @if (loading)
            {
                <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"spinner-border spinner-border-sm mr-1"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
            }
            Extract Text
        <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<p>We have defined the route for this component. We have inherited the <code>OCRModel</code> class which allows us to access the properties and method of this class from the template. Bootstrap is used for designing the UI. We have a text area to display the detected text and a text box to display the detected language. The image tag is used to show the image preview after uploading the image. The <code>&lt;InputFile&gt;</code> component will allow us to upload an image file and invoke the <code>ViewImage</code> method as we upload the image.</p>
<h2 id="heading-add-styling-for-the-component">Add styling for the component</h2>
<p>Navigate to <code>[BlazorComputerVision\wwwroot\css\site.css](https://github.com/AnkitSharma-007/Blazor-Computer-Vision-Azure-Cognitive-Services/blob/master/BlazorComputerVision/wwwroot/css/site.css#L185-L197)</code> file and add the following style definition inside it.</p>
<pre><code class="lang-css"><span class="hljs-selector-class">.preview-image</span> {
    <span class="hljs-attribute">max-height</span>: <span class="hljs-number">300px</span>;
    <span class="hljs-attribute">max-width</span>: <span class="hljs-number">300px</span>;
}
<span class="hljs-selector-class">.image-container</span> {
    <span class="hljs-attribute">display</span>: flex;
    <span class="hljs-attribute">padding</span>: <span class="hljs-number">15px</span>;
    <span class="hljs-attribute">align-content</span>: center;
    <span class="hljs-attribute">align-items</span>: center;
    <span class="hljs-attribute">justify-content</span>: center;
    <span class="hljs-attribute">border</span>: <span class="hljs-number">2px</span> dashed skyblue;
}
</code></pre>
<h2 id="heading-adding-link-to-navigation-menu"><strong>Adding Link to Navigation menu</strong></h2>
<p>The last step is to add the link of our OCR component in the navigation menu. Open <code>[BlazorComputerVision/Shared/NavMenu.razor](https://github.com/AnkitSharma-007/Blazor-Computer-Vision-Azure-Cognitive-Services/blob/master/BlazorComputerVision/Shared/NavMenu.razor#L15-L19)</code> file and add the following code into it.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"nav-item px-3"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">NavLink</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"nav-link"</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"computer-vision-ocr"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"oi oi-list-rich"</span> <span class="hljs-attr">aria-hidden</span>=<span class="hljs-string">"true"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span> Computer Vision
    <span class="hljs-tag">&lt;/<span class="hljs-name">NavLink</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
</code></pre>
<p>Remove the navigation links for Counter and Fetch-data components as they are not required for this application.</p>
<h2 id="heading-execution-demo">Execution Demo</h2>
<p>Press F5 to launch the application. Click on the Computer Vision button on the nav menu on the left. On the next page, upload an image with some text in it and click on the “Extract Text” button. You will see the extracted text in the text area on the left along with the detected language for the text. Refer to the image shown below.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/Execution_English.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Now we will try to upload an image with some French text on it, you can see the extracted text and the detected language as French. Refer to the image shown below.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/Execution_French.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>If we try to upload an image with an unsupported language, we will get the error. Refer to the image shown below where an image with text written in Hindi is uploaded.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/Execution_Hindi.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-summary"><strong>Summary</strong></h2>
<p>We have created an optical character recognition (OCR) application using Blazor and the Computer Vision Azure Cognitive Service. We have added the feature of uploading an image file using the <code>BlazorInputFile</code> component. The application is able to extract the printed text from the uploaded image and recognizes the language of the text. The OCR API of the Computer Vision is used which can recognize text in 25 languages.</p>
<p>Get the Source code from <a target="_blank" href="https://github.com/AnkitSharma-007/Blazor-Computer-Vision-Azure-Cognitive-Services">GitHub</a> and play around to get a better understanding.</p>
<h2 id="heading-see-also">See Also</h2>
<ul>
<li><a target="_blank" href="https://ankitsharmablogs.com/multi-language-translator-using-blazor-and-azure-cognitive-services/">Multi-Language Translator Using Blazor And Azure Cognitive Services</a></li>
<li><a target="_blank" href="https://ankitsharmablogs.com/facebook-authentication-and-authorization-in-server-side-blazor-app/">Facebook Authentication And Authorization In Server-Side Blazor App</a></li>
<li><a target="_blank" href="https://ankitsharmablogs.com/google-authentication-and-authorization-in-server-side-blazor-app/">Google Authentication And Authorization In Server-Side Blazor App</a></li>
<li><a target="_blank" href="https://ankitsharmablogs.com/policy-based-authorization-in-angular-using-jwt/">Policy-Based Authorization In Angular Using JWT</a></li>
<li><a target="_blank" href="https://ankitsharmablogs.com/continuous-deployment-for-angular-app-using-heroku-and-github/">Continuous Deployment For Angular App Using Heroku And GitHub</a></li>
<li><a target="_blank" href="https://ankitsharmablogs.com/hosting-a-blazor-application-on-firebase/">Hosting A Blazor Application on Firebase</a></li>
<li><a target="_blank" href="https://ankitsharmablogs.com/deploying-a-blazor-application-on-azure/">Deploying A Blazor Application On Azure</a></li>
</ul>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Implement Google Authentication and Authorization in a Server-Side Blazor App ]]>
                </title>
                <description>
                    <![CDATA[ By Ankit Sharma Introduction The latest preview for .NET Core 3 (preview-6) has introduced the functionality to add authentication and authorization in a server-side Blazor application. In this article, we will learn how to implement authentication a... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-implement-google-authentication-and-authorization-in-server-side-blazor-app/</link>
                <guid isPermaLink="false">66d45db9680e33282da25e31</guid>
                
                    <category>
                        <![CDATA[ authentication ]]>
                    </category>
                
                    <category>
                        <![CDATA[ autherization ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Blazor ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Google ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Thu, 11 Jul 2019 06:13:10 +0000</pubDate>
                <media:content url="https://cdn-media-2.freecodecamp.org/w1280/5f9ca187740569d1a4ca4f1d.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Ankit Sharma</p>
<h2 id="heading-introduction"><strong>Introduction</strong></h2>
<p>The latest preview for .NET Core 3 (preview-6) has introduced the functionality to add authentication and authorization in a server-side Blazor application. In this article, we will learn how to implement authentication and authorization using Google in a server-side Blazor application. You can refer to my previous article <a target="_blank" href="https://ankitsharmablogs.com/understanding-server-side-blazor/">Understanding Server-side Blazor</a> to get in-depth knowledge on server-side Blazor.</p>
<h2 id="heading-prerequisites"><strong>Prerequisites</strong></h2>
<ul>
<li>Install the latest .NET Core 3.0 Preview SDK from <a target="_blank" href="https://dotnet.microsoft.com/download/dotnet-core/3.0">here</a>.</li>
<li>Install the latest preview of Visual Studio 2019 from <a target="_blank" href="https://visualstudio.com/preview">here</a>.</li>
<li>Install ASP.NET Core Blazor Language Services extension from <a target="_blank" href="https://go.microsoft.com/fwlink/?linkid=870389">here</a>.</li>
</ul>
<h2 id="heading-source-code"><strong>Source Code</strong></h2>
<p>Get the source code from <a target="_blank" href="https://github.com/AnkitSharma-007/Google-Authentication-with-server-side-Blazor">GitHub</a></p>
<h2 id="heading-create-server-side-blazor-application"><strong>Create Server Side Blazor Application</strong></h2>
<p>To create a server-side Blazor app, open Visual Studio 2019 and follow the steps mentioned below.</p>
<ol>
<li>Click on “Create a new project”.</li>
<li>Select “ASP.NET Core Web Application” from available project types. Click on Next.</li>
<li>A new “Configure your new project” screen will open. Put the name of the project as <code>BlazorGoogleAuth</code> and click Create.</li>
<li>In the next screen, select “.NET Core” and “ASP.NET Core 3.0” from dropdowns on the top left.</li>
<li>Select “Blazor (server-side)” from the list of available templates.</li>
<li>Click on Change Authentication button, a “Change Authentication” dialog box will open. Select “Individual User Account” and click OK. Click on <code>Create</code> button to create the application.</li>
</ol>
<p>These steps are shown in the GIF image below.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/06/BlazorGoogleAuth.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Before running the application, we need to apply migrations to our app. Navigate to Tools &gt;&gt; NuGet Package Manager &gt;&gt; Package Manager Console.</p>
<p>It will open the Package Manager Console. Put in <code>Update-Database</code> command and hit enter. This will update the database using Entity Framework Code First Migrations.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/06/DBrestore.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Open project properties by right clicking on the project in solution explorer and select properties. Select Debug from left side menu then scroll to the bottom of the page. Note the SSL enabled URL. In this case, the URL is <code>https://localhost:44327/</code>. We need this URL to configure the Google API Console project which we will be doing in our next section. Refer to the image below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/06/ProjectProperties.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-create-a-google-api-console-project"><strong>Create a Google API Console project</strong></h2>
<p>We need to create a Google API console project and obtain a client ID and client secret to configure the Google authentication in our application.</p>
<p>Navigate to <a target="_blank" href="https://developers.google.com/identity/sign-in/web/sign-in#before_you_begin">https://developers.google.com/identity/sign-in/web/sign-in#before_you_begin</a>. Login with your Google account. Follow the steps mentioned below.</p>
<ol>
<li>Click on “Configure a Project” button.</li>
<li>A “Configure a project for Google Sign-in” dialog box will open asking you to select or create a new project.</li>
<li>Select “Create a new project” from the dropdown. Name your project “BlazorAuthDemo” and click on Next.</li>
<li>In the “Configure your OAuth client” screen, put your product name. You can use any name of your choice. Here we will put “BlazorAuth” as the product name.</li>
<li>In the next screen, select “Web server” from the “Where are you calling from” dropdown.</li>
<li>It will then ask you to put the “Authorized redirect URIs”. Give the base URL of your application with <code>/signin-google</code> appended to it. For this tutorial, the URL will be <code>https://localhost:44327/signin-google</code>.</li>
<li>Click on Create. The dialog box will now prompt you with the client ID and client secret. Make a note of <code>ClientId</code> and <code>ClientSecret</code> field. We will need these values to configure Google authentication in our web app</li>
</ol>
<p>Refer to the GIF below for a better understanding.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/06/GoogleAuthProject.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<blockquote>
<ul>
<li>Do not use the word “Google” in your product name. You will be prompted with an error and you will not be allowed to create the app. This means “BlazorGoogleAuth” is an invalid project name.</li>
<li>Project names must be between 4 and 30 characters and may only contain letters, numbers, spaces, and hyphens.</li>
</ul>
</blockquote>
<h2 id="heading-installing-google-authentication-middleware-nuget-package"><strong>Installing Google authentication middleware NuGet package</strong></h2>
<p>To configure the ASP.NET Core middleware for Google authentication we need to install the <code>Microsoft.AspNetCore.Authentication.Google</code> nuget package in our application. The version of this nuget package must match the version of .NET Core 3 which we are using in our project.</p>
<p>Open <a target="_blank" href="https://www.nuget.org/packages/Microsoft.AspNetCore.Authentication.Google/">https://www.nuget.org/packages/Microsoft.AspNetCore.Authentication.Google/</a>. Select the version of .NET Core 3 from the “Version History”. Copy the command from the “package manager” tab. Run this command in the NuGet package manager console of our application.</p>
<p>For this application, we are using <code>.NET Core 3.0.0-preview6.19307.2</code>. Therefore, we will run the following command in the package manager console of our application.</p>
<pre><code>Install-Package Microsoft.AspNetCore.Authentication.Google -Version <span class="hljs-number">3.0</span><span class="hljs-number">.0</span>-preview6<span class="hljs-number">.19307</span><span class="hljs-number">.2</span>
</code></pre><p>Refer to the image below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/06/NugetInstall.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-configure-the-server-side-blazor-app-to-use-google-authentication"><strong>Configure the server-side Blazor app to use Google authentication</strong></h2>
<p>We need to store <code>ClientId</code> and <code>ClientSecret</code> field values in our application. We will use Secret Manager tool for this purpose. The Secret Manager tool is a project tool that can be used to store secrets such as password, API Key, etc. for a .NET Core project during the development process. With the Secret Manager tool, we can associate app secrets with a specific project and can share them across multiple projects.</p>
<p>Open our web application once again and Right-click the project in the Solution Explorer. Select Manage User Secrets from the context menu. A <code>secrets.json</code> file will open. Put the following code in it.</p>
<pre><code>{
  <span class="hljs-string">"Authentication:Google:ClientId"</span>: <span class="hljs-string">"Your Google ClientId here"</span>,
  <span class="hljs-string">"Authentication:Google:ClientSecret"</span>: <span class="hljs-string">"Your Google ClientSecret here"</span>
}
</code></pre><p>Now open <code>Startup.cs</code> file and put the following code into <code>ConfigureServices</code> method.</p>
<pre><code>services.AddAuthentication().AddGoogle(<span class="hljs-function"><span class="hljs-params">googleOptions</span> =&gt;</span>
{
  googleOptions.ClientId = Configuration[<span class="hljs-string">"Authentication:Google:ClientId"</span>];
  googleOptions.ClientSecret = Configuration[<span class="hljs-string">"Authentication:Google:ClientSecret"</span>];
});
</code></pre><p>This code will read the <code>ClientId</code> and <code>ClientSecret</code> from the <code>secrets.json</code> file. The <code>AddGoogle()</code>method is an extension method and it is used to configure the Google Authentication options for our application.</p>
<h2 id="heading-adding-authorization-to-blazor-pages"><strong>Adding authorization to Blazor pages</strong></h2>
<p>Blazor has added a new built-in component called <code>AuthorizeView</code>, which is used to display different content based on the authentication state of the application. This component will display the child component only when the user is authorized.  The <code>AuthorizeView</code> component is configured in <code>\Shared\LoginDisplay.razor</code> file.</p>
<p>To implement authorization to a specific page, we need to use the <code>[Authorize]</code> attribute. Blazor has introduced a new directive <code>@attribute</code>, which is used to include the <code>[Authorize]</code> attribute for a page. In this application, we will apply <code>[Authorize]</code> to the FetchData component. This will prohibit unauthorized access to this component. Open <code>FetchData.razor</code> page and add the following lines at the top of the page.</p>
<pre><code>@using Microsoft.AspNetCore.Authorization
@attribute [Authorize]
</code></pre><h2 id="heading-execution-demo"><strong>Execution Demo</strong></h2>
<p>Launch the application. Navigate to Fetch Data component by clicking on the “Fetch data” link on the menu on the left. You will see a “Not authorized” message displayed on the screen. Click “Log In” on the menu at the top. In the next page click on the “Google” button to login with Google. Once you are logged in successfully, you will be able to access the Fetch Data component.</p>
<p>Refer to the GIF below for a better understanding.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/06/BlazorGoogleauthExecution.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-conclusion"><strong>Conclusion</strong></h2>
<p>We learned how to implement Google authentication and authorization in a server-side Blazor application. We have created and configured a Google API console project to implement Google authentication. To implement authorization for a specific component in Blazor, we have used the [Authorize] attribute. We have used <code>Microsoft.AspNetCore.Authentication.Google</code> nuget package to configure the middleware for Google authentication.</p>
<p>Please get the source code from <a target="_blank" href="https://github.com/AnkitSharma-007/Google-Authentication-with-server-side-Blazor">GitHub</a> and play around to get a better understanding.</p>
<p>Get my book <a target="_blank" href="https://amzn.to/2OToEji">Blazor Quick Start Guide</a> to learn more about Blazor.</p>
<p>Preparing for interviews !!! Read my article on <a target="_blank" href="https://ankitsharmablogs.com/csharp-coding-questions-for-technical-interviews/">C# Coding Questions For Technical Interviews</a></p>
<h2 id="heading-see-also"><strong>See Also</strong></h2>
<ul>
<li><a target="_blank" href="https://ankitsharmablogs.com/blazorgrid-reusable-grid-component-for-blazor/">BlazorGrid – A Reusable Grid Component For Blazor</a></li>
<li><a target="_blank" href="https://ankitsharmablogs.com/publishing-blazor-component-to-nuget-gallery/">Publishing A Blazor Component To Nuget Gallery</a></li>
<li><a target="_blank" href="https://ankitsharmablogs.com/deploying-a-blazor-application-on-azure/">Deploying A Blazor Application On Azure</a></li>
<li><a target="_blank" href="https://ankitsharmablogs.com/hosting-a-blazor-application-on-firebase/">Hosting A Blazor Application on Firebase</a></li>
<li><a target="_blank" href="https://ankitsharmablogs.com/blazor-crud-using-google-cloud-firestore/">Blazor CRUD Using Google Cloud Firestore</a></li>
<li><a target="_blank" href="https://ankitsharmablogs.com/crud-using-blazor-with-mongodb/">CRUD Using Blazor with MongoDB</a></li>
<li><a target="_blank" href="https://ankitsharmablogs.com/single-page-application-using-server-side-blazor/">Single Page Application Using Server-Side Blazor</a></li>
</ul>
<p><em>Originally published at <a target="_blank" href="https://ankitsharmablogs.com/google-authentication-and-authorization-in-server-side-blazor-app/">https://ankitsharmablogs.com/google-authentication-and-authorization-in-server-side-blazor-app/</a></em></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to perform CRUD operations using Blazor and Google Cloud Firestore ]]>
                </title>
                <description>
                    <![CDATA[ By Ankit Sharma Introduction In this article, we will create a Blazor application using Google Firstore as database provider. We will create a Single Page Application (SPA) and perform CRUD operations on it. We will use Bootstrap 4 to display a modal... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-perform-crud-operations-using-blazor-and-google-cloud-firestore-52890b06e2f8/</link>
                <guid isPermaLink="false">66d45dbf33b83c4378a517c6</guid>
                
                    <category>
                        <![CDATA[ Blazor ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Firebase ]]>
                    </category>
                
                    <category>
                        <![CDATA[ General Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tech  ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Fri, 15 Mar 2019 15:51:12 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*muHjpi3rrHCyXSoIqoK7Iw.gif" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Ankit Sharma</p>
<h3 id="heading-introduction">Introduction</h3>
<p>In this article, we will create a Blazor application using Google Firstore as database provider. We will create a Single Page Application (SPA) and perform CRUD operations on it. We will use Bootstrap 4 to display a modal popup for handling user inputs. The form also has a dropdown list, which will bind to a collection in our database. We will also implement a client-side search functionality to search the employee list by employee name.</p>
<p>Take a look at the final application.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/W7b2ndw04cr4wdIHtI2olU2LYkePZaq5Fh33" alt="Image" width="650" height="366" loading="lazy"></p>
<h3 id="heading-prerequisites">Prerequisites</h3>
<ul>
<li>Install the .NET Core 2.1 or above SDK from <a target="_blank" href="https://www.microsoft.com/net/learn/get-started-with-dotnet-tutorial#windowscmd">here</a></li>
<li>Install latest version of Visual Studio 2017 from <a target="_blank" href="https://www.visualstudio.com/downloads/">here</a></li>
<li>Install ASP.NET Core Blazor Language Services extension from <a target="_blank" href="https://marketplace.visualstudio.com/items?itemName=aspnet.blazor">here</a></li>
</ul>
<h3 id="heading-source-code">Source Code</h3>
<p>Get the source code from <a target="_blank" href="https://github.com/AnkitSharma-007/Blazor-CRUD-With-CloudFirestore">GitHub</a>.</p>
<h3 id="heading-configuring-cloud-firestore">Configuring Cloud Firestore</h3>
<p>The first step is to create a project in google Firebase console. Navigate to <a target="_blank" href="https://console.firebase.google.com/">https://console.firebase.google.com</a> and sign-in with your google account. Click on Add Project link. A pop up window will open as shown in the image below. Provide your project name and click on Create project button at the bottom.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/IUhsu1yB0vg-JFpejfs-1V6lm22XajPQsF6G" alt="Image" width="567" height="700" loading="lazy"></p>
<p>Note the project id here. Firebase project ids are globally unique. You can edit your project id while creating a new project. Once the project is created you cannot change your project id. We will use this project id in next section while initializing our application.</p>
<p>Click on the project you just created. A project overview page will open. Select “Database” from left menu. Then click on “Create database” button. A popup window will open asking you to select the “Security rules for Cloud Firestore”. Select “Start in locked mode” and click on enable.</p>
<p>Refer to the image below:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1f8jEpvnl1svzglTyJkp51RmOpcnzcGkeEFj" alt="Image" width="650" height="357" loading="lazy"></p>
<p>This will enable the database for your project. Firebase project have two options for database — Realtime Database and Cloud Firestore. For this application, we will use “Cloud Firestore” database. Click on “Database” dropdown at the top of the page and select “Cloud Firestore”.</p>
<p>Refer to the image below:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/bYGk2T-Rvk1AqCB9HgMkHz07T-iiCeTSpPPX" alt="Image" width="500" height="295" loading="lazy"></p>
<p>We will create cities collection to store the city name for employees. We will also bind this collection to a dropdown list in our web application from which the user will select the desired city. Click on “Add collection”. Set the collection ID as “cities”. Click on “Next”. Refer to the image below:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/PRjBhrBH7VofY1Mdn-ENX2gEzd9Uo6zf4hrY" alt="Image" width="600" height="313" loading="lazy"></p>
<p>Put the Field value as “CityName”, Select string from the Type dropdown and fill the value with city name as “Mumbai”. Click on Save. Refer to the image below:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/W8G7ATIkDBVliNQlTzBYHiAaGBAleX-W-NLF" alt="Image" width="650" height="485" loading="lazy"></p>
<p>This will create the “cities” collection and insert the first document in it. Similarly, create four more documents inside this collection and put the “CityName” value as Chennai, New Delhi, Bengaluru and Hyderabad.</p>
<p>We will use “employees” collection to store employee data, but we will not create it manually. We will create “employees” collection while adding the first employee data from the application.</p>
<h3 id="heading-configuring-google-application-credentials">Configuring Google Application Credentials</h3>
<p>To access database from our project, we need to set the <code>GOOGLE_APPLICATION_CREDENTIALS</code> environment variable to point to a JSON service account key file. This will set an authentication pipeline from our application to cloud Firestore.</p>
<p>To generate the service account key file follow the steps mentioned below:</p>
<p><strong>Step 1</strong>: Navigate to <a target="_blank" href="https://console.cloud.google.com/iam-admin/">https://console.cloud.google.com/iam-admin/</a>. Login with the same google account, you have used to create Firestore DB.</p>
<p><strong>Step 2</strong>: Select Project from the drop down in menu bar at the top.</p>
<p><strong>Step 3</strong>: Select “Service accounts” from the left menu. Select the service account for which you want to create the key. Click on more button in the “Actions” column in that row, and then click Create key.</p>
<p>Refer to the image below:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/9IHtUREAUoK49PnqL0Dwz5VbGQQgHFP4J0fU" alt="Image" width="650" height="293" loading="lazy"></p>
<p><strong>Step 4</strong>: A popup modal will open asking you to select the key type. Select “JSON” and click on create button. This will create private key for accessing your Firestore account and downloads a JSON key file to your machine. We will use this file to set <code>GOOGLE_APPLICATION_CREDENTIALS</code> environment variable in later part of this article.</p>
<h3 id="heading-create-blazor-web-application">Create Blazor Web Application</h3>
<p>Open Visual Studio and select File &gt;&gt; New &gt;&gt; Project. After selecting the project, a “New Project” dialog will open. Select .NET Core inside Visual C# menu from the left panel. Then, select “ASP.NET Core Web Application” from available project types. Put the name of the <code>project as BlazorW</code>ithFirestore and press OK.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/yK4DI82EB76voCsnfmJaj5KmKwmjhaFwmeF9" alt="Image" width="650" height="355" loading="lazy"></p>
<p>After clicking on OK, a new dialog will open asking you to select the project template. You can observe two drop-down menus at the top left of the template window. Select “.NET Core” and “ASP.NET Core 2.1” from these dropdowns. Then, select “Blazor (ASP .NET Core hosted)” template and press OK.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/oq3ARrgxpuIWNZ-riZRsvEeB4QVe5QT2GTq7" alt="Image" width="650" height="461" loading="lazy"></p>
<p>Now, our Blazor solution will be created. You can observe that we have three project files created in this solution.</p>
<ol>
<li>BlazorWithFirestore.Client — It has the client side code and contains the pages that will be rendered on the browser.</li>
<li>BlazorWithFirestore.Server — It has the server side codes such as data access layer and web API.</li>
<li>BlazorWithFirestore.Shared — It contains the shared code that can be accessed by both client and server. It contains our Model classes.</li>
</ol>
<h3 id="heading-adding-package-reference-for-firestore">Adding Package reference for Firestore</h3>
<p>We need to add the package reference for Google cloud Firestore, which will allow us to access our DB from the Blazor application. Right click on <code>BlazorWithFirestore.Shared</code> project.</p>
<p>Select “Edit BlazorWithFirestore.Shared.csproj”. It will open the <code>BlazorWithFirestore.Shared.csproj</code> file. Add the following lines inside it.</p>
<pre><code>&lt;ItemGroup&gt;  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">PackageReference</span> <span class="hljs-attr">Include</span>=<span class="hljs-string">"Google.Cloud.Firestore"</span> <span class="hljs-attr">Version</span>=<span class="hljs-string">"1.0.0-beta14"</span> /&gt;</span></span>&lt;/ItemGroup&gt;
</code></pre><p>Similarly add these lines to <code>BlazorWithFirestore.Server.csproj</code> file also.</p>
<h3 id="heading-creating-the-model">Creating the Model</h3>
<p>We will create our model class in <code>BlazorWithFirestore.Shared</code> project. Right click on <code>BlazorWithFirestore.Shared</code> and select Add &gt;&gt; New Folder. Name the folder as Models. Again, right click on Models folder and select Add &gt;&gt; Class to add a new class file. Put the name of you class as Employee.cs and click Add.</p>
<p>Open the <code>Employee.cs</code> class and put the following code into it.</p>
<pre><code>using System;using Google.Cloud.Firestore;namespace BlazorWithFirestore.Shared.Models{    [FirestoreData]    public <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Employee</span>    </span>{        public string EmployeeId { get; set; }        public DateTime date { get; set; }        [FirestoreProperty]        public string EmployeeName { get; set; }        [FirestoreProperty]        public string CityName { get; set; }        [FirestoreProperty]        public string Designation { get; set; }        [FirestoreProperty]        public string Gender { get; set; }    }}
</code></pre><p>We have decorated the class with <code>[FirestoreData]</code> attribute. This will allow us to map this class object to Firestore collection. Only those class properties, which are marked with <code>[FirestoreProperty]</code> attribute, are considered when we are saving the document to our collection. We do not need to save EmployeeId to our database as it is generated automatically.</p>
<p>While fetching the data, we will bind the auto generated document id to the EmployeeId property. Similarly, we will use date property to bind the created date of collection while fetching the record. We will use this date property to sort the list of employees by created date. Hence, we have not applied <code>[FirestoreProperty]</code> attribute to these two properties.</p>
<p>Similarly, create a class file Cities.cs and put the following code into it.</p>
<pre><code>using System;using Google.Cloud.Firestore;namespace BlazorWithFirestore.Shared.Models{    [FirestoreData]    public <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Cities</span>    </span>{        public string CityName { get; set; }    }}
</code></pre><h3 id="heading-creating-data-access-layer-for-the-application">Creating Data Access Layer for the Application</h3>
<p>Right-click on <code>BlazorWithFirestore.Server</code> project and then select Add &gt;&gt; New Folder and name the fold<code>er as Data</code>Access. We will be adding our class to handle database related operations inside this folder only. Right click on DataAccess folder and select Add &gt;&gt; Class. Name <code>your class EmployeeDataAc</code>cessLayer.cs.</p>
<p>Put the following code inside this class.</p>
<pre><code>using System;using System.Collections.Generic;using System.Linq;using System.Threading.Tasks;using BlazorWithFirestore.Shared.Models;using Google.Cloud.Firestore;using Newtonsoft.Json;namespace BlazorWithFirestore.Server.DataAccess{    public <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">EmployeeDataAccessLayer</span>    </span>{        string projectId;        FirestoreDb fireStoreDb;        public EmployeeDataAccessLayer()        {            string filepath = <span class="hljs-string">"C:\\FirestoreAPIKey\\blazorwithfirestore-6d0a096b0174.json"</span>;            Environment.SetEnvironmentVariable(<span class="hljs-string">"GOOGLE_APPLICATION_CREDENTIALS"</span>, filepath);            projectId = <span class="hljs-string">"blazorwithfirestore"</span>;            fireStoreDb = FirestoreDb.Create(projectId);        }        public <span class="hljs-keyword">async</span> Task&lt;List&lt;Employee&gt;&gt; GetAllEmployees()        {            <span class="hljs-keyword">try</span>            {                Query employeeQuery = fireStoreDb.Collection(<span class="hljs-string">"employees"</span>);                QuerySnapshot employeeQuerySnapshot = <span class="hljs-keyword">await</span> employeeQuery.GetSnapshotAsync();                List&lt;Employee&gt; lstEmployee = <span class="hljs-keyword">new</span> List&lt;Employee&gt;();                foreach (DocumentSnapshot documentSnapshot <span class="hljs-keyword">in</span> employeeQuerySnapshot.Documents)                {                    <span class="hljs-keyword">if</span> (documentSnapshot.Exists)                    {                        Dictionary&lt;string, object&gt; city = documentSnapshot.ToDictionary();                        string json = JsonConvert.SerializeObject(city);                        Employee newuser = JsonConvert.DeserializeObject&lt;Employee&gt;(json);                        newuser.EmployeeId = documentSnapshot.Id;                        newuser.date = documentSnapshot.CreateTime.Value.ToDateTime();                        lstEmployee.Add(newuser);                    }                }                List&lt;Employee&gt; sortedEmployeeList = lstEmployee.OrderBy(<span class="hljs-function"><span class="hljs-params">x</span> =&gt;</span> x.date).ToList();                <span class="hljs-keyword">return</span> sortedEmployeeList;            }            <span class="hljs-keyword">catch</span>            {                <span class="hljs-keyword">throw</span>;            }        }        public <span class="hljs-keyword">async</span> <span class="hljs-keyword">void</span> AddEmployee(Employee employee)        {            <span class="hljs-keyword">try</span>            {                CollectionReference colRef = fireStoreDb.Collection(<span class="hljs-string">"employees"</span>);                <span class="hljs-keyword">await</span> colRef.AddAsync(employee);            }            <span class="hljs-keyword">catch</span>            {                <span class="hljs-keyword">throw</span>;            }        }        public <span class="hljs-keyword">async</span> <span class="hljs-keyword">void</span> UpdateEmployee(Employee employee)        {            <span class="hljs-keyword">try</span>            {                DocumentReference empRef = fireStoreDb.Collection(<span class="hljs-string">"employees"</span>).Document(employee.EmployeeId);                <span class="hljs-keyword">await</span> empRef.SetAsync(employee, SetOptions.Overwrite);            }            <span class="hljs-keyword">catch</span>            {                <span class="hljs-keyword">throw</span>;            }        }        public <span class="hljs-keyword">async</span> Task&lt;Employee&gt; GetEmployeeData(string id)        {            <span class="hljs-keyword">try</span>            {                DocumentReference docRef = fireStoreDb.Collection(<span class="hljs-string">"employees"</span>).Document(id);                DocumentSnapshot snapshot = <span class="hljs-keyword">await</span> docRef.GetSnapshotAsync();                <span class="hljs-keyword">if</span> (snapshot.Exists)                {                    Employee emp = snapshot.ConvertTo&lt;Employee&gt;();                    emp.EmployeeId = snapshot.Id;                    <span class="hljs-keyword">return</span> emp;                }                <span class="hljs-keyword">else</span>                {                    <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> Employee();                }            }            <span class="hljs-keyword">catch</span>            {                <span class="hljs-keyword">throw</span>;            }        }        public <span class="hljs-keyword">async</span> <span class="hljs-keyword">void</span> DeleteEmployee(string id)        {            <span class="hljs-keyword">try</span>            {                DocumentReference empRef = fireStoreDb.Collection(<span class="hljs-string">"employees"</span>).Document(id);                <span class="hljs-keyword">await</span> empRef.DeleteAsync();            }            <span class="hljs-keyword">catch</span>            {                <span class="hljs-keyword">throw</span>;            }        }        public <span class="hljs-keyword">async</span> Task&lt;List&lt;Cities&gt;&gt; GetCityData()        {            <span class="hljs-keyword">try</span>            {                Query citiesQuery = fireStoreDb.Collection(<span class="hljs-string">"cities"</span>);                QuerySnapshot citiesQuerySnapshot = <span class="hljs-keyword">await</span> citiesQuery.GetSnapshotAsync();                List&lt;Cities&gt; lstCity = <span class="hljs-keyword">new</span> List&lt;Cities&gt;();                foreach (DocumentSnapshot documentSnapshot <span class="hljs-keyword">in</span> citiesQuerySnapshot.Documents)                {                    <span class="hljs-keyword">if</span> (documentSnapshot.Exists)                    {                        Dictionary&lt;string, object&gt; city = documentSnapshot.ToDictionary();                        string json = JsonConvert.SerializeObject(city);                        Cities newCity = JsonConvert.DeserializeObject&lt;Cities&gt;(json);                        lstCity.Add(newCity);                    }                }                <span class="hljs-keyword">return</span> lstCity;            }            <span class="hljs-keyword">catch</span>            {                <span class="hljs-keyword">throw</span>;            }        }    }}
</code></pre><p>In the constructor of this class we are setting the <code>GOOGLE_APPLICATION_CREDENTIALS</code> environment variable. You need to set the value of filepath variable to the path where the JSON service account key file is located in your machine. Remember we downloaded this file in the previous section. The projectId variable should be set to the project id of your Firebase project.</p>
<p>We have also defined the methods for performing CRUD operations. The GetAllEmployees method will fetch the list of all employee document from our “employees” collection. It will return the employee list sorted by document creation date.</p>
<p>The <code>AddEmployee</code> method will add a new employee document to our “employees” collection. If the collection does not exist, it will create the collection first then insert a new document in it.</p>
<p>The <code>UpdateEmployee</code> method will update the field values of an already existing employee document, based on the employee id passed to it. We are binding the document id to employeeId property, hence we can easily manipulate the documents.</p>
<p>The <code>GetEmployeeData</code> method will fetch a single employee document from our “employees” collection based on the employee id.</p>
<p><code>DeleteEmployee</code> method will delete the document for a particular employee from the “employees” collection.</p>
<p><code>GetCityData</code> method will return the list of cities from “cities” collection.</p>
<h3 id="heading-adding-the-web-api-controller-to-the-application">Adding the web API Controller to the Application</h3>
<p>Right-click on <code>BlazorWithFirestore.Server/Controllers</code> folder and select Add &gt;&gt; New Item. An “Add New Item” dialog box will open. Select Web from the left panel, then select “API Controller Class” from templates panel and put the na<code>me as EmployeeControl</code>ler.cs. Click Add.</p>
<p>This will create our API EmployeeController class. We will call the methods of EmployeeDataAccessLayer class to fetch data and pass on the data to the client side.</p>
<p>Open <code>EmployeeController.cs</code> file and put the following code into it.</p>
<pre><code>using System;using System.Collections.Generic;using System.Threading.Tasks;using BlazorWithFirestore.Server.DataAccess;using BlazorWithFirestore.Shared.Models;using Microsoft.AspNetCore.Mvc;namespace BlazorWithFirestore.Server.Controllers{    [Route(<span class="hljs-string">"api/[controller]"</span>)]    public <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">EmployeeController</span> : <span class="hljs-title">Controller</span>    </span>{        EmployeeDataAccessLayer objemployee = <span class="hljs-keyword">new</span> EmployeeDataAccessLayer();        [HttpGet]        public Task&lt;List&lt;Employee&gt;&gt; Get()        {            <span class="hljs-keyword">return</span> objemployee.GetAllEmployees();        }        [HttpGet(<span class="hljs-string">"{id}"</span>)]        public Task&lt;Employee&gt; Get(string id)        {            <span class="hljs-keyword">return</span> objemployee.GetEmployeeData(id);        }        [HttpPost]        public <span class="hljs-keyword">void</span> Post([FromBody] Employee employee)        {            objemployee.AddEmployee(employee);        }        [HttpPut]        public <span class="hljs-keyword">void</span> Put([FromBody]Employee employee)        {            objemployee.UpdateEmployee(employee);        }        [HttpDelete(<span class="hljs-string">"{id}"</span>)]        public <span class="hljs-keyword">void</span> Delete(string id)        {            objemployee.DeleteEmployee(id);        }        [HttpGet(<span class="hljs-string">"GetCities"</span>)]        public Task&lt;List&lt;Cities&gt;&gt; GetCities()        {            <span class="hljs-keyword">return</span> objemployee.GetCityData();        }    }}
</code></pre><h3 id="heading-creating-the-blazor-component">Creating the Blazor component</h3>
<p>We will create the component in the <code>BlazorWithFirestore.Client/Pages</code> folder. The application template provides the Counter and Fetch Data files by default in this folder. Before adding our own component file, we will delete these two default files to make our solution cleaner. Right-click on <code>BlazorWithFirestore.Client/Pages</code> folder and then select Add &gt;&gt; New Item. An “Add New Item” dialog box will open, select “ASP.NET Core” from the left panel, then select “Razor Page” from templates panel and na<code>me it EmployeeData.</code>cshtml. Click Add. Refer to the image below:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/Op5ktwMN2KAvOvrDx0M3ez3qA8uj3-5Y5ljt" alt="Image" width="650" height="372" loading="lazy"></p>
<p>This will add an <code>EmployeeData.cshtml</code> page to our BlazorSPA.Client/Pages folder. This razor page will have two files – EmployeeData.cshtml and EmployeeData.cshtml.cs.</p>
<h3 id="heading-adding-references-for-js-interop">Adding references for JS Interop</h3>
<p>We will be using a bootstrap modal dialog in our application. We will also include a few Font Awesome icons for styling in the application. To be able to use these two libraries, we need to add the CDN references to allow the JS interop.</p>
<pre><code>&lt;link rel=<span class="hljs-string">"stylesheet"</span> href=<span class="hljs-string">"https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"</span>&gt;<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span></span><span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span></span><span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://maxcdn.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span></span>
</code></pre><p>Here, we have included the CDN references, which will allow us to use the bootstrap modal dialog and Font Awesome icons in our applications. Now, we will add codes to our view files.</p>
<h3 id="heading-employeedatacshtmlcs">EmployeeData.cshtml.cs</h3>
<p>Open <code>EmployeeData.cshtml.cs</code> and put the following code into it.</p>
<pre><code>using System;using System.Collections.Generic;using System.Linq;using System.Net.Http;using System.Threading.Tasks;using BlazorWithFirestore.Shared.Models;using Microsoft.AspNetCore.Blazor;using Microsoft.AspNetCore.Blazor.Components;namespace BlazorWithFirestore.Client.Pages{    public <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">EmployeeDataModel</span> : <span class="hljs-title">BlazorComponent</span>    </span>{        [Inject]        protected HttpClient Http { get; set; }        protected List&lt;Employee&gt; empList = <span class="hljs-keyword">new</span> List&lt;Employee&gt;();        protected List&lt;Cities&gt; cityList = <span class="hljs-keyword">new</span> List&lt;Cities&gt;();        protected Employee emp = <span class="hljs-keyword">new</span> Employee();        protected string modalTitle { get; set; }        protected string searchString { get; set; }        protected override <span class="hljs-keyword">async</span> Task OnInitAsync()        {            <span class="hljs-keyword">await</span> GetCityList();            <span class="hljs-keyword">await</span> GetEmployeeList();        }        protected <span class="hljs-keyword">async</span> Task GetCityList()        {            cityList = <span class="hljs-keyword">await</span> Http.GetJsonAsync&lt;List&lt;Cities&gt;&gt;(<span class="hljs-string">"api/Employee/GetCities"</span>);        }        protected <span class="hljs-keyword">async</span> Task GetEmployeeList()        {            empList = <span class="hljs-keyword">await</span> Http.GetJsonAsync&lt;List&lt;Employee&gt;&gt;(<span class="hljs-string">"api/Employee"</span>);        }        protected <span class="hljs-keyword">void</span> AddEmployee()        {            emp = <span class="hljs-keyword">new</span> Employee();            modalTitle = <span class="hljs-string">"Add Employee"</span>;        }        protected <span class="hljs-keyword">async</span> Task EditEmployee(string empID)        {            emp = <span class="hljs-keyword">await</span> Http.GetJsonAsync&lt;Employee&gt;(<span class="hljs-string">"/api/Employee/"</span> + empID);            modalTitle = <span class="hljs-string">"Edit Employee"</span>;        }        protected <span class="hljs-keyword">async</span> Task SaveEmployee()        {            <span class="hljs-keyword">if</span> (emp.EmployeeId != <span class="hljs-literal">null</span>)            {                <span class="hljs-keyword">await</span> Http.SendJsonAsync(HttpMethod.Put, <span class="hljs-string">"api/Employee/"</span>, emp);            }            <span class="hljs-keyword">else</span>            {                <span class="hljs-keyword">await</span> Http.SendJsonAsync(HttpMethod.Post, <span class="hljs-string">"/api/Employee/"</span>, emp);            }            <span class="hljs-keyword">await</span> GetEmployeeList();        }        protected <span class="hljs-keyword">async</span> Task DeleteConfirm(string empID)        {            emp = <span class="hljs-keyword">await</span> Http.GetJsonAsync&lt;Employee&gt;(<span class="hljs-string">"/api/Employee/"</span> + empID);        }        protected <span class="hljs-keyword">async</span> Task DeleteEmployee(string empID)        {            Console.WriteLine(empID);            <span class="hljs-keyword">await</span> Http.DeleteAsync(<span class="hljs-string">"api/Employee/"</span> + empID);            <span class="hljs-keyword">await</span> GetEmployeeList();        }        protected <span class="hljs-keyword">async</span> Task SearchEmployee()        {            <span class="hljs-keyword">await</span> GetEmployeeList();            <span class="hljs-keyword">if</span> (searchString != <span class="hljs-string">""</span>)            {                empList = empList.Where(                <span class="hljs-function"><span class="hljs-params">x</span> =&gt;</span> x.EmployeeName.IndexOf(searchString,                StringComparison.OrdinalIgnoreCase) != <span class="hljs-number">-1</span>).ToList();            }        }    }}
</code></pre><p>Here, we have defined the EmployeeDataModel class, which is inheriting from BlazorComponent. This allows the EmployeeDataModel class to act as a Blazor component.</p>
<p>We are also injecting the HttpClient service to enable the web API calls to our EmployeeController API.</p>
<p>We will use the two variables — empList and cityList — to hold the data of our Employee and Cities collections respectively. The modalTitle property, which is of type string, is used to hold the title that will be displayed in the modal dialog. The value provided in the search box is stored in the searchString property which is also of type string.</p>
<p>The <code>GetCityList</code> method will make a call to our web API GetCities method to fetch the list of city data from the cities collection. The <code>GetEmployeeList</code> method will send a GET request to our web API to fetch the list of Employee Data from the Employee table.</p>
<p>We are invoking these two methods inside the <code>OnInitAsync</code> method, to ensure that the Employee Data and the cities data will be available as the page loads.</p>
<p>The <code>AddEmployee</code> method will initialize an empty instance of the Employee object and set the modalTitle property, which will display the title message on the Add modal popup.</p>
<p>The <code>EditEmployee</code> method will accept the employee ID as the parameter. It will send a GET request to our web API to fetch the record of the employee corresponding to the employee ID supplied to it.</p>
<p>We will use the <code>SaveEmployee</code> method to save the record of the employee for both the Add request and Edit request. To differentiate between the Add and the Edit requests, we will use the EmployeeId property of the Employee object. If an Edit request is made, then the EmployeeId property contains a string value, and we will send a PUT request to our web API, which will update the record of the employee. Otherwise, if we make an Add request, then the EmployeeId property is not initialized, and hence it will be null. In this case, we need to send a POST request to our web API, which will create a new employee record.</p>
<p>The <code>DeleteConfirm</code> method will accept the employee ID as the parameter. It will fetch the Employee Data corresponding to the employee ID supplied to it.</p>
<p>The <code>DeleteEmployee</code> method will send a delete request to our API and pass the employee ID as the parameter. It will then call the GetEmployeeList method to refresh the view with the updated list of Employee Data.</p>
<p>The <code>SearchEmployee</code> method is used to implement the search by the employee name functionality. We will return all the records of the employee, which will match the search criteria either fully or partially. To make the search more effective, we will ignore the text case of the search string. This means the search result will be same whether the search text is in uppercase or in lowercase.</p>
<h3 id="heading-employeedatacshtml">EmployeeData.cshtml</h3>
<p>Open <code>EmployeeData.cshtml</code> page and put the following code into it.</p>
<pre><code>@page <span class="hljs-string">"/employeerecords"</span>@inherits EmployeeDataModel&lt;h1&gt;Employee Data&lt;<span class="hljs-regexp">/h1&gt;&lt;div class="container"&gt;    &lt;div class="row"&gt;        &lt;div class="col-xs-3"&gt;            &lt;button class="btn btn-primary" data-toggle="modal" data-target="#AddEditEmpModal" onclick="@AddEmployee"&gt;                &lt;i class="fa fa-user-plus"&gt;&lt;/i</span>&gt;                Add Employee            &lt;<span class="hljs-regexp">/button&gt;        &lt;/</span>div&gt;        <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"input-group col-md-4 offset-md-5"</span>&gt;</span>            <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-control"</span> <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Search Employee"</span> <span class="hljs-attr">bind</span>=<span class="hljs-string">"@searchString"</span> /&gt;</span>            <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"input-group-append"</span>&gt;</span>                <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"btn btn-info"</span> <span class="hljs-attr">onclick</span>=<span class="hljs-string">"@SearchEmployee"</span>&gt;</span>                    <span class="hljs-tag">&lt;<span class="hljs-name">i</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"fa fa-search"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">i</span>&gt;</span>                <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>            <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>    &lt;<span class="hljs-regexp">/div&gt;&lt;/</span>div&gt;<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">br</span> /&gt;</span></span>@<span class="hljs-keyword">if</span> (empList == <span class="hljs-literal">null</span>){    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">em</span>&gt;</span>Loading...<span class="hljs-tag">&lt;/<span class="hljs-name">em</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></span>}<span class="hljs-keyword">else</span>{    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">table</span> <span class="hljs-attr">class</span>=<span class="hljs-string">'table'</span>&gt;</span>        <span class="hljs-tag">&lt;<span class="hljs-name">thead</span>&gt;</span>            <span class="hljs-tag">&lt;<span class="hljs-name">tr</span>&gt;</span>                <span class="hljs-tag">&lt;<span class="hljs-name">th</span>&gt;</span>Name<span class="hljs-tag">&lt;/<span class="hljs-name">th</span>&gt;</span>                <span class="hljs-tag">&lt;<span class="hljs-name">th</span>&gt;</span>Gender<span class="hljs-tag">&lt;/<span class="hljs-name">th</span>&gt;</span>                <span class="hljs-tag">&lt;<span class="hljs-name">th</span>&gt;</span>Designation<span class="hljs-tag">&lt;/<span class="hljs-name">th</span>&gt;</span>                <span class="hljs-tag">&lt;<span class="hljs-name">th</span>&gt;</span>City<span class="hljs-tag">&lt;/<span class="hljs-name">th</span>&gt;</span>            <span class="hljs-tag">&lt;/<span class="hljs-name">tr</span>&gt;</span>        <span class="hljs-tag">&lt;/<span class="hljs-name">thead</span>&gt;</span>        <span class="hljs-tag">&lt;<span class="hljs-name">tbody</span>&gt;</span>            @foreach (var emp in empList)            {                <span class="hljs-tag">&lt;<span class="hljs-name">tr</span>&gt;</span>                    <span class="hljs-tag">&lt;<span class="hljs-name">td</span>&gt;</span>@emp.EmployeeName<span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>                    <span class="hljs-tag">&lt;<span class="hljs-name">td</span>&gt;</span>@emp.Gender<span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>                    <span class="hljs-tag">&lt;<span class="hljs-name">td</span>&gt;</span>@emp.Designation<span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>                    <span class="hljs-tag">&lt;<span class="hljs-name">td</span>&gt;</span>@emp.CityName<span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>                    <span class="hljs-tag">&lt;<span class="hljs-name">td</span>&gt;</span>                        <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"btn btn-outline-dark"</span> <span class="hljs-attr">data-toggle</span>=<span class="hljs-string">"modal"</span> <span class="hljs-attr">data-target</span>=<span class="hljs-string">"#AddEditEmpModal"</span>                                <span class="hljs-attr">onclick</span>=<span class="hljs-string">"@(async () =&gt; await EditEmployee(@emp.EmployeeId))"</span>&gt;</span>                            <span class="hljs-tag">&lt;<span class="hljs-name">i</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"fa fa-pencil-square-o"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">i</span>&gt;</span>                            Edit                        <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>                        <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"btn btn-outline-danger"</span> <span class="hljs-attr">data-toggle</span>=<span class="hljs-string">"modal"</span> <span class="hljs-attr">data-target</span>=<span class="hljs-string">"#deleteEmpModal"</span>                                <span class="hljs-attr">onclick</span>=<span class="hljs-string">"@(async () =&gt; await DeleteConfirm(@emp.EmployeeId))"</span>&gt;</span>                            <span class="hljs-tag">&lt;<span class="hljs-name">i</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"fa fa-trash-o"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">i</span>&gt;</span>                            Delete                        <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>                    <span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>                <span class="hljs-tag">&lt;/<span class="hljs-name">tr</span>&gt;</span>            }        <span class="hljs-tag">&lt;/<span class="hljs-name">tbody</span>&gt;</span>    <span class="hljs-tag">&lt;/<span class="hljs-name">table</span>&gt;</span></span>}&lt;div <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"modal fade"</span> id=<span class="hljs-string">"AddEditEmpModal"</span>&gt;    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"modal-dialog"</span>&gt;</span>        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"modal-content"</span>&gt;</span>            <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"modal-header"</span>&gt;</span>                <span class="hljs-tag">&lt;<span class="hljs-name">h3</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"modal-title"</span>&gt;</span>@modalTitle<span class="hljs-tag">&lt;/<span class="hljs-name">h3</span>&gt;</span>                <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"button"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"close"</span> <span class="hljs-attr">data-dismiss</span>=<span class="hljs-string">"modal"</span>&gt;</span>                    <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">aria-hidden</span>=<span class="hljs-string">"true"</span>&gt;</span>X<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>                <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>            <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>            <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"modal-body"</span>&gt;</span>                <span class="hljs-tag">&lt;<span class="hljs-name">form</span>&gt;</span>                    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-group"</span>&gt;</span>                        <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"control-label"</span>&gt;</span>Name<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>                        <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-control"</span> <span class="hljs-attr">bind</span>=<span class="hljs-string">"@emp.EmployeeName"</span> /&gt;</span>                    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>                    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-group"</span>&gt;</span>                        <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"control-label"</span>&gt;</span>Gender<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>                        <span class="hljs-tag">&lt;<span class="hljs-name">select</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-control"</span> <span class="hljs-attr">bind</span>=<span class="hljs-string">"@emp.Gender"</span>&gt;</span>                            <span class="hljs-tag">&lt;<span class="hljs-name">option</span> <span class="hljs-attr">value</span>=<span class="hljs-string">""</span>&gt;</span>-- Select Gender --<span class="hljs-tag">&lt;/<span class="hljs-name">option</span>&gt;</span>                            <span class="hljs-tag">&lt;<span class="hljs-name">option</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"Male"</span>&gt;</span>Male<span class="hljs-tag">&lt;/<span class="hljs-name">option</span>&gt;</span>                            <span class="hljs-tag">&lt;<span class="hljs-name">option</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"Female"</span>&gt;</span>Female<span class="hljs-tag">&lt;/<span class="hljs-name">option</span>&gt;</span>                        <span class="hljs-tag">&lt;/<span class="hljs-name">select</span>&gt;</span>                    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>                    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-group"</span>&gt;</span>                        <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"control-label"</span>&gt;</span>Designation<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>                        <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-control"</span> <span class="hljs-attr">bind</span>=<span class="hljs-string">"@emp.Designation"</span> /&gt;</span>                    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>                    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-group"</span>&gt;</span>                        <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"control-label"</span>&gt;</span>City<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>                        <span class="hljs-tag">&lt;<span class="hljs-name">select</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-control"</span> <span class="hljs-attr">bind</span>=<span class="hljs-string">"@emp.CityName"</span>&gt;</span>                            <span class="hljs-tag">&lt;<span class="hljs-name">option</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"-- Select City --"</span>&gt;</span>-- Select City --<span class="hljs-tag">&lt;/<span class="hljs-name">option</span>&gt;</span>                            @foreach (var city in cityList)                            {                                <span class="hljs-tag">&lt;<span class="hljs-name">option</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"@city.CityName"</span>&gt;</span>@city.CityName<span class="hljs-tag">&lt;/<span class="hljs-name">option</span>&gt;</span>                            }                        <span class="hljs-tag">&lt;/<span class="hljs-name">select</span>&gt;</span>                    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>                <span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>            <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>            <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"modal-footer"</span>&gt;</span>                <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"btn btn-block btn-success"</span>                        <span class="hljs-attr">onclick</span>=<span class="hljs-string">"@(async () =&gt; await SaveEmployee())"</span> <span class="hljs-attr">data-dismiss</span>=<span class="hljs-string">"modal"</span>&gt;</span>                    Save                <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>            <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>&lt;<span class="hljs-regexp">/div&gt;&lt;div class="modal fade" id="deleteEmpModal"&gt;    &lt;div class="modal-dialog"&gt;        &lt;div class="modal-content"&gt;            &lt;div class="modal-header"&gt;                &lt;h3 class="modal-title"&gt;Confirm Delete !!!&lt;/</span>h3&gt;                <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"button"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"close"</span> <span class="hljs-attr">data-dismiss</span>=<span class="hljs-string">"modal"</span>&gt;</span>                    <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">aria-hidden</span>=<span class="hljs-string">"true"</span>&gt;</span>X<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>                <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span>            &lt;<span class="hljs-regexp">/div&gt;            &lt;div class="modal-body"&gt;                &lt;table class="table"&gt;                    &lt;tr&gt;                        &lt;td&gt;Name&lt;/</span>td&gt;                        <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">td</span>&gt;</span>@emp.EmployeeName<span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span></span>                    &lt;<span class="hljs-regexp">/tr&gt;                    &lt;tr&gt;                        &lt;td&gt;Gender&lt;/</span>td&gt;                        <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">td</span>&gt;</span>@emp.Gender<span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span></span>                    &lt;<span class="hljs-regexp">/tr&gt;                    &lt;tr&gt;                        &lt;td&gt;Designation&lt;/</span>td&gt;                        <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">td</span>&gt;</span>@emp.Designation<span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span></span>                    &lt;<span class="hljs-regexp">/tr&gt;                    &lt;tr&gt;                        &lt;td&gt;City&lt;/</span>td&gt;                        <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">td</span>&gt;</span>@emp.CityName<span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span></span>                    &lt;<span class="hljs-regexp">/tr&gt;                &lt;/</span>table&gt;            &lt;<span class="hljs-regexp">/div&gt;            &lt;div class="modal-footer"&gt;                &lt;button class="btn btn-danger" data-dismiss="modal"                        onclick="@(async () =&gt; await DeleteEmployee(@emp.EmployeeId))"&gt;                    Delete                &lt;/</span>button&gt;                <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">data-dismiss</span>=<span class="hljs-string">"modal"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"btn"</span>&gt;</span>Cancel<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span>            &lt;<span class="hljs-regexp">/div&gt;        &lt;/</span>div&gt;    &lt;<span class="hljs-regexp">/div&gt;&lt;/</span>div&gt;
</code></pre><p>The route for our component is defined at the top as “/employeerecords”. To use the methods defined in the EmployeeDataModel class, we will inherit it using the <code>@inherits</code> directive.</p>
<p>We have defined an Add Employee button. Upon clicking, this button will invoke the <code>AddEmployee</code> method and open a modal dialog, which allows the user to fill out the new Employee Data in a form.</p>
<p>We have also defined our search box and a corresponding search button. The search box will bind the value to searchString property. On clicking the search button, <code>SearchEmployee</code> method will be invoked, which will return the filtered list of data as per the search text. If the empList property is not null, we will bind the Employee Data to a table to display it on the web page. Each employee record has the following two action buttons corresponding to it:</p>
<ul>
<li>Edit: This button will perform two tasks. It will invoke the EditEmployee method and open the edit employee modal dialog for editing the employee record.</li>
<li>Delete: This button will also perform two tasks. It will invoke the DeleteConfirm method and open a delete confirm modal dialog, asking the user to confirm the deletion of the employee’s record .</li>
</ul>
<p>We have defined a form inside the bootstrap modal to accept user inputs for the employee records. The input fields of this form will bind to the properties of the employee class. The City field is a drop-down list, which will bind to the cities collection of the database with the help of the cityList variable. When we click on the save button, the <code>SaveEmployee</code> method will be invoked and the modal dialog will be closed.</p>
<p>When user click on the Delete button corresponding to an employee record, another bootstrap modal dialog will be displayed. This modal will show the Employee Data in a table and ask the user to confirm the deletion. Clicking on the Delete button inside this modal dialog will invoke the DeleteEmployee method and close the modal. Clicking on the Cancel button will close the modal without performing any action on the data.</p>
<h3 id="heading-adding-the-navigation-link-to-our-component">Adding the navigation link to our component</h3>
<p>Before executing the application, we will add the navigation link to our component in the navigation menu.</p>
<p>Open the <code>BlazorWithFirestore.Client/Shared/NavMenu.cshtml</code> page and add the following navigation link:</p>
<pre><code>&lt;li <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"nav-item px-3"</span>&gt;  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">NavLink</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"nav-link"</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"employeerecords"</span>&gt;</span>    <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"oi oi-list-rich"</span> <span class="hljs-attr">aria-hidden</span>=<span class="hljs-string">"true"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span> Employee Data  <span class="hljs-tag">&lt;/<span class="hljs-name">NavLink</span>&gt;</span></span>&lt;/li&gt;
</code></pre><p>Hence, we have successfully created a Single Page Application (SPA) using Blazor with the help of cloud Firestore as database provider.</p>
<h3 id="heading-execution-demo">Execution Demo</h3>
<p>Press F5 to launch the application.</p>
<p>A web page will open as shown in the image below. The navigation menu on the left is showing navigation link for Employee data page.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/HxKudv9nbDAz4bUBjCJee7r1o5Dfqn2lXuyf" alt="Image" width="650" height="375" loading="lazy"></p>
<p>You can perform the CRUD operations on this application as shown in the GIF image at the start of this article.</p>
<h3 id="heading-conclusion">Conclusion</h3>
<p>We have created a Single Page Application (SPA) using Blazor with the help of Google cloud Firestore as database provider. We have created a sample employee record management system and performed CRUD operations on it. Firestore is a NoSQL database, which allows us to store data in form of collections and documents. We have also used a bootstrap modal popup to handle user inputs. We have also implemented a search box to search the employee list by employee name.</p>
<p>Please get the source code from <a target="_blank" href="https://github.com/AnkitSharma-007/Blazor-CRUD-With-CloudFirestore">GitHub</a> and play around to get a better understanding.</p>
<p>Get my book <a target="_blank" href="https://amzn.to/2OToEji">Blazor Quick Start Guide</a> to learn more about Blazor.</p>
<p>Preparing for interviews? Read my article on <a target="_blank" href="https://ankitsharmablogs.com/csharp-coding-questions-for-technical-interviews/">C# Coding Questions For Technical Interviews</a></p>
<h3 id="heading-see-also">See Also</h3>
<ul>
<li><a target="_blank" href="https://ankitsharmablogs.com/blazorgrid-reusable-grid-component-for-blazor/">BlazorGrid — A Reusable Grid Component For Blazor</a></li>
<li><a target="_blank" href="https://ankitsharmablogs.com/publishing-blazor-component-to-nuget-gallery/">Publishing A Blazor Component To Nuget Gallery</a></li>
<li><a target="_blank" href="https://ankitsharmablogs.com/deploying-a-blazor-application-on-iis/">Deploying a Blazor Application on IIS</a></li>
<li><a target="_blank" href="https://ankitsharmablogs.com/deploying-a-blazor-application-on-azure/">Deploying A Blazor Application On Azure</a></li>
<li><a target="_blank" href="https://ankitsharmablogs.com/hosting-a-blazor-application-on-firebase/">Hosting A Blazor Application on Firebase</a></li>
<li><a target="_blank" href="https://ankitsharmablogs.com/crud-using-blazor-with-mongodb/">CRUD Using Blazor with MongoDB</a></li>
<li><a target="_blank" href="https://ankitsharmablogs.com/single-page-application-using-server-side-blazor/">Single Page Application Using Server-Side Blazor</a></li>
</ul>
<p>Originally published at <a target="_blank" href="https://ankitsharmablogs.com/">https://ankitsharmablogs.com/</a></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How To Host a Blazor Application on Firebase ]]>
                </title>
                <description>
                    <![CDATA[ By Ankit Sharma Introduction In this article, we will learn how to deploy a Blazor application on Firebase. We will create a basic calculator app using Blazor and host it on Firebase. This application will not have any server-side code or web API log... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-host-a-blazor-application-on-firebase-67c4ee956a22/</link>
                <guid isPermaLink="false">66d45db5246e57ac83a2c719</guid>
                
                    <category>
                        <![CDATA[ Apps ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Blazor ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Firebase ]]>
                    </category>
                
                    <category>
                        <![CDATA[ General Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tech  ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Thu, 24 Jan 2019 22:10:24 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*dhtbZon7OPebZuUO9-yyjw.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Ankit Sharma</p>
<h3 id="heading-introduction">Introduction</h3>
<p>In this article, we will learn how to deploy a Blazor application on Firebase. We will create a basic calculator app using Blazor and host it on Firebase. This application will not have any server-side code or web API logic. We will use Visual Studio 2017 to build and publish the application. We will use CLI to deploy the application on Firebase.</p>
<h3 id="heading-prerequisites">Prerequisites</h3>
<p>You need to install following prerequisites to create a Blazor application.</p>
<ul>
<li>Install the .NET Core 2.1 or above SDK from <a target="_blank" href="https://www.microsoft.com/net/learn/get-started-with-dotnet-tutorial#windowscmd">here</a></li>
<li>Install the latest version of Visual Studio 2017 from <a target="_blank" href="https://www.visualstudio.com/downloads/">here</a></li>
<li>Install ASP.NET Core Blazor Language Services extension from <a target="_blank" href="https://marketplace.visualstudio.com/items?itemName=aspnet.blazor">here</a></li>
</ul>
<h3 id="heading-creating-a-blazor-application">Creating a Blazor application</h3>
<p>We will create a basic calculator application for this demo. Since this is a basic calculator, it will take two operands, and support four arithmetic functions — addition, subtraction, multiplication, and division.</p>
<p>Open Visual Studio and select File &gt;&gt; New &gt;&gt; Project. After selecting the project, a “New Project” dialog will open. Select .NET Core inside Visual C# menu from the left panel. T<code>hen, select ASP.NET Core Web</code> Application from available project types. Put the name of the <code>project as Samp</code>leCalculator and press OK.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/HuinX8HUzvMpywjRLq-bk-6cvRBxJEDEAniC" alt="Image" width="650" height="372" loading="lazy"></p>
<p>After clicking on OK, a new dialog will open asking you to select the project template. You can observe two drop-down menus at the top left of the template window. Select “.NET Core” and “ASP.NET Core 2.1” from these dropdowns. Then, select “Blazor” template and press OK.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/xZ-fGQWc75D0gQ3UGMipKHlDFuDZv0Q02m93" alt="Image" width="650" height="457" loading="lazy"></p>
<p>This will create your Blazor application. We will now create our calculator component.</p>
<h3 id="heading-creating-the-calculator-component">Creating the Calculator Component</h3>
<p>For this application, we will use the single page component structure. The logic and the UI will be in the same file.</p>
<p>To create our component, right-click on <code>SampleCalculator/Pages</code> folder and then select Add &gt;&gt; New Item. An Add New Item dialog box will open, asking you to select the desired item template from the provided list of items. Select ASP.NET Core from the left panel, and then select Razor View from the templates panel. Put the name of fi<code>le as Calculator.</code>cshtml and click Add.</p>
<p>Refer to the following screenshot:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/IOK1Vg6Pr1FX2dXJfCkmNSKtsCFQ2r7FWRTo" alt="Image" width="650" height="349" loading="lazy"></p>
<p>Open the <code>Calculator.cshtml</code> file and put the following code into it:</p>
<pre><code>@page <span class="hljs-string">"/calculator"</span>&lt;h1&gt;Basic Calculator Using Blazor&lt;<span class="hljs-regexp">/h1&gt;&lt;hr /</span>&gt;<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"row"</span>&gt;</span>        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"col-sm-3"</span>&gt;</span>            <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"control-label"</span>&gt;</span>First Number<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"col-sm-4"</span>&gt;</span>            <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-control"</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Enter First Number"</span> <span class="hljs-attr">bind</span>=<span class="hljs-string">"@operand1"</span> /&gt;</span>        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>    <span class="hljs-tag">&lt;<span class="hljs-name">br</span> /&gt;</span>    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"row"</span>&gt;</span>        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"col-sm-3"</span>&gt;</span>            <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"control-label"</span>&gt;</span>Second Number<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"col-sm-4"</span>&gt;</span>            <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-control"</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Enter Second Number"</span> <span class="hljs-attr">bind</span>=<span class="hljs-string">"@operand2"</span> /&gt;</span>        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>    <span class="hljs-tag">&lt;<span class="hljs-name">br</span> /&gt;</span>    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"row"</span>&gt;</span>        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"col-sm-3"</span>&gt;</span>            <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"control-label"</span>&gt;</span>Result<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"col-sm-4"</span>&gt;</span>            <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">readonly</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-control"</span> <span class="hljs-attr">bind</span>=<span class="hljs-string">"@finalResult"</span> /&gt;</span>        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>    <span class="hljs-tag">&lt;<span class="hljs-name">br</span> /&gt;</span>    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"row"</span>&gt;</span>        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"col-md-3"</span>&gt;</span>            <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onclick</span>=<span class="hljs-string">"@AddNumbers"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"btn btn-primary"</span>&gt;</span>                Add                (+)            <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"col-md-3"</span>&gt;</span>            <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onclick</span>=<span class="hljs-string">"@SubtractNumbers"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"btn btnwarning"</span>&gt;</span>Subtract (−)<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"col-md-3"</span>&gt;</span>            <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onclick</span>=<span class="hljs-string">"@MultiplyNumbers"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"btn btn-success"</span>&gt;</span>Multiply (X)<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"col-md-3"</span>&gt;</span>            <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onclick</span>=<span class="hljs-string">"@DivideNumbers"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"btn btn-info"</span>&gt;</span>Divide (/)<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>@functions {double operand1 { get; set; }double operand2 { get; set; }string finalResult { get; set; }<span class="hljs-keyword">void</span> AddNumbers(){    finalResult = (operand1 + operand2).ToString();}<span class="hljs-keyword">void</span> SubtractNumbers(){    finalResult = (operand1 - operand2).ToString();}<span class="hljs-keyword">void</span> MultiplyNumbers(){    finalResult = (operand1 * operand2).ToString();}<span class="hljs-keyword">void</span> DivideNumbers(){    <span class="hljs-keyword">if</span> (operand2 != <span class="hljs-number">0</span>)    {        finalResult = (operand1 / operand2).ToString();    }    <span class="hljs-keyword">else</span>    {        finalResult = <span class="hljs-string">"Cannot Divide by Zero"</span>;    }}}
</code></pre><p>In the HTML part of the code, we have defined two textboxes to read the operand input from the user. We have a textbox to display the result of arithmetic operations. We have also defined four buttons, one for each arithmetic operation. The onclick event of the buttons will invoke the methods that will provide the output. Once it has performed the corresponding operation on both operands.</p>
<p>In the @functions section, we have defined two properties to bind to the user input value, and another property to display the calculation result. To handle our arithmetic operations, we have defined four methods that will perform the desired operations on the operands and set the value of finalResult that will then bind to the Result field on the UI.</p>
<p>Add the navigation link for this component in <code>Shared/NavMenu.cshtml</code> file. Press F5 to run the application and you can see the output screen as shown in the image below:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/bKgUV3hORWxMnSk2UnoIEukeUIMiWcRJMYir" alt="Image" width="650" height="385" loading="lazy"></p>
<p>This application is still in a development environment. Before hosting it on Firebase, we need to publish it.</p>
<h3 id="heading-publishing-the-blazor-application">Publishing the Blazor application</h3>
<p>Right click on the project and click publish. Refer to the image below:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/ZjihqY84OTyVvaJzaqyVe5ey42SyGeE8j1iT" alt="Image" width="650" height="665" loading="lazy"></p>
<p>You will see a screen similar to below. Select Folder from the left menu and provide a folder path. You can provide any folder path where you want to publish your app.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/aXzPfCQwg7P7ju9Pv8nwP9h2M4m-1VdGuokg" alt="Image" width="650" height="487" loading="lazy"></p>
<p>Click on publish. Visual Studio will start publishing your application. If there are no build errors then your application will be published successfully to the folder you have mentioned.</p>
<p>After the publishing is successful, we will proceed to host this application on Firebase.</p>
<h3 id="heading-adding-project-on-firebase">Adding Project on Firebase</h3>
<p>The first step to host any application on Firebase is to add a new project on Firebase console.</p>
<p>Navigate to <a target="_blank" href="https://console.firebase.google.com/">https://console.firebase.google.com</a> and sign in with your Google account. Click on <code>Add Project</code> link. A pop up window will open as shown in the image below. Provide your project name and click on <code>Create project</code> button at the bottom.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/e88YyTpLOYUyMPWNlt7BRm9D9SGKJQ1pE1zz" alt="Image" width="555" height="700" loading="lazy"></p>
<p>Note the project id here. Firebase project ids are globally unique. You can edit your project id while creating a new project. One the project is created you cannot change your project id. We will use this project id in the next section while initializing our application.</p>
<h3 id="heading-deploying-with-firebase">Deploying with Firebase</h3>
<p>Open the folder where you have published your Blazor application. Here you can see a folder “SampleCalculator” and a web.config file. Inside “SampleCalculator” we will have another folder with name “dist”. We will publish the contents from this “dist” folder.</p>
<p>Open a command prompt/PowerShell window inside the “SampleCalculator” folder. Now follow the steps mentioned below:</p>
<p><strong>Step 1</strong>: Login using Firebase</p>
<p>Execute the following command:</p>
<pre><code>firebase login
</code></pre><p>It will open a browser window and ask you to login into Firebase. Login using your Google account. Upon successful login navigate back to your CLI.</p>
<p><strong>Step 2</strong>: Initializing your application</p>
<p>Execute the following command</p>
<pre><code>firebase init
</code></pre><p>This command will initialize a firebase project. You will be asked a set of questions. Answer them as shown below:</p>
<ul>
<li>Are you ready to proceed? — Press Y</li>
<li>Which Firebase CLI features do you want to set up for this folder? — select Hosting</li>
<li>Select a default Firebase project for this directory: — If the project you added in the last section appears in the list, select it, else select “don’t set up a default project”.</li>
<li>What do you want to use as your public directory? — dist</li>
<li>Configure as a single-page app (rewrite all URLs to /index.html)? — y</li>
<li>File dist/index.html already exists. Overwrite? — N</li>
</ul>
<p>You will get a “Firebase initialization complete!” message.</p>
<p><strong>Step 3</strong>: Adding a default project</p>
<p>If you already selected a default project in step 2 then you can skip this step.</p>
<p>If you have not selected a default project then you need to add it manually here. Run the following command:</p>
<pre><code>firebase use --add yourProjectId
</code></pre><p>In this case, it will be</p>
<pre><code>firebase use --add blazorcalc
</code></pre><p>You will get a success message as “Now using project blazorcalc”.</p>
<p><strong>Step 4</strong>: Deploy on Firebase</p>
<p>Finally, run the following command to deploy your application on Firebase.</p>
<pre><code>firebase deploy
</code></pre><p>This command will deploy your Blazor application on Firebase and upon success, it will give you a hosting URL.</p>
<p>All the steps mentioned above is shown in the GIF below:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/8LWcAiWcrmbuU2TeTFCkUG2yEpQSR0LxJxzR" alt="Image" width="650" height="339" loading="lazy"></p>
<h3 id="heading-execution-demo">Execution Demo</h3>
<p>Open the hosting URL. You can see the application in your browser as shown in the image below:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/Yc-a1ikqx961hS2NN8u9WAnXmQt0ojPO0Id1" alt="Image" width="650" height="430" loading="lazy"></p>
<h3 id="heading-article-extension">Article Extension</h3>
<p>We can follow the same steps to host an Angular application on Firebase.</p>
<p>Run the following command to build an Angular app for prod.</p>
<pre><code>ng build --prod
</code></pre><p>It will create the “dist” folder in your application’s root folder. Once you get the “dist” folder follow the same steps as mentioned above.</p>
<h3 id="heading-conclusion">Conclusion</h3>
<p>We learned how to create a sample calculator application using Blazor. We also learned how to deploy this application to Firebase.</p>
<p>You can find the code for this sample calculator application at <a target="_blank" href="https://github.com/AnkitSharma-007/ASPCore.BlazorDemo">Github</a>.</p>
<p>Get my book <a target="_blank" href="https://amzn.to/2OToEji">Blazor Quick Start Guide</a> to learn more about Blazor.</p>
<p>Preparing for interviews? Read my article on <a target="_blank" href="https://ankitsharmablogs.com/csharp-coding-questions-for-technical-interviews/">C# Coding Questions For Technical Interviews</a></p>
<h3 id="heading-see-also">See Also</h3>
<ul>
<li><a target="_blank" href="https://ankitsharmablogs.com/blazorgrid-reusable-grid-component-for-blazor/">BlazorGrid — A Reusable Grid Component For Blazor</a></li>
<li><a target="_blank" href="https://ankitsharmablogs.com/publishing-blazor-component-to-nuget-gallery/">Publishing A Blazor Component To Nuget Gallery</a></li>
<li><a target="_blank" href="https://ankitsharmablogs.com/deploying-a-blazor-application-on-iis/">Deploying a Blazor Application on IIS</a></li>
<li><a target="_blank" href="https://ankitsharmablogs.com/deploying-a-blazor-application-on-azure/">Deploying A Blazor Application On Azure</a></li>
<li><a target="_blank" href="https://ankitsharmablogs.com/crud-using-blazor-with-mongodb/">CRUD Using Blazor with MongoDB</a></li>
<li><a target="_blank" href="https://ankitsharmablogs.com/single-page-application-using-server-side-blazor/">Single Page Application Using Server-Side Blazor</a></li>
</ul>
<p>Originally published at <a target="_blank" href="https://ankitsharmablogs.com/">https://ankitsharmablogs.com/</a></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to deploy a Blazor Application on Internet Information Services (IIS) ]]>
                </title>
                <description>
                    <![CDATA[ By Ankit Sharma Introduction In this article, we will learn how to deploy an ASP.NET Core hosted Blazor application with the help of IIS 10 on a Windows 10 machine. We will be using Visual Studio 2017 to publish the app and SQL Server 2014 to handle ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-deploy-a-blazor-application-on-internet-information-services-iis-f96f2969fdcb/</link>
                <guid isPermaLink="false">66d45db14a7504b7409c3338</guid>
                
                    <category>
                        <![CDATA[ Apps ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Blazor ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Microsoft ]]>
                    </category>
                
                    <category>
                        <![CDATA[ General Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ technology ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Thu, 14 Jun 2018 15:12:33 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*qZqIAFSLGBjADpNTsnu9Pw.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Ankit Sharma</p>
<h3 id="heading-introduction">Introduction</h3>
<p>In this article, we will learn how to deploy an ASP.NET Core hosted Blazor application with the help of IIS 10 on a Windows 10 machine. We will be using Visual Studio 2017 to publish the app and SQL Server 2014 to handle DB operations. We will also troubleshoot some of the common hosting issues for a Blazor application.</p>
<h3 id="heading-prerequisites">Prerequisites</h3>
<ul>
<li>Install IIS in your machine</li>
<li>Install URL Rewrite module from <a target="_blank" href="https://www.iis.net/downloads/microsoft/url-rewrite">here</a></li>
</ul>
<p>Please refer to my previous article, <a target="_blank" href="https://medium.freecodecamp.org/how-to-create-a-cascading-dropdownlist-in-blazor-using-ef-core-d230bb5bff5f">How to create a cascading DropDownList in Blazor using EF Core</a>, to create the application that we will be deploying in this tutorial.</p>
<h3 id="heading-installing-net-core-hosting-bundle"><strong>Installing .NET Core hosting bundle</strong></h3>
<p>Since we are going to deploy an ASP.NET Core hosted Blazor application, the first step is to install the .NET Core hosting bundle in our machine.</p>
<p>Follow the below steps to download the .NET Core hosting bundle:</p>
<h4 id="heading-step-1"><strong>Step 1</strong></h4>
<p>Open <a target="_blank" href="https://www.microsoft.com/net/download/all">https://www.microsoft.com/net/download/all</a></p>
<h4 id="heading-step-2"><strong>Step 2</strong></h4>
<p>Select the latest non-preview .NET Core runtime from the list. For this tutorial, we will select .NET Core Runtime 2.0.7.</p>
<p>Refer to the image below:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/yP2moxch5u2x6B6mUdKoT4PRFIKtScQSZgqp" alt="Image" width="340" height="296" loading="lazy"></p>
<h4 id="heading-step-3"><strong>Step 3</strong></h4>
<p>On the .NET Core runtime download page, scroll down to Windows section, select the “Hosting Bundle Installer” link to download the “.NET Core Hosting Bundle”<em>.</em> Refer to the image below:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/blMT51CVhgidICtzTNRUxy3XfyyHMysiXuSN" alt="Image" width="400" height="348" loading="lazy"></p>
<p>Once the download is finished, double-click to start installing it. You will see a window similar to the one shown below:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/jWrEFc9edDlLk9VwB8yRaXKDUiSUQHPRQj-7" alt="Image" width="650" height="396" loading="lazy"></p>
<h4 id="heading-important-note"><strong>Important Note</strong></h4>
<ol>
<li>The .NET Core hosting bundle should be installed only after installing IIS. If you the bundle before installing IIS then you need to repair the bundle after installing IIS so that it will update its dependencies for IIS.</li>
<li>Restart the machine after installing the .NET Core hosting bundle.</li>
</ol>
<h3 id="heading-publishing-the-blazor-application">Publishing the Blazor application</h3>
<p>Once the .NET Core hosting bundle installation is successful and you have restarted your machine, open the Blazor application solution using VS 2017.</p>
<p>Right click on the Server project of your solution and click publish. In this case it will be BlazorDDL.Server &gt;&gt; Publish.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/9SX4ook9WusBea8tm8oajC4uxAsxZJ5cGcye" alt="Image" width="650" height="640" loading="lazy"></p>
<p>You will see a screen similar to what’s shown below. Select Folder from the left menu and provide a folder path. You can provide any folder path where you want to publish your app.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/p7U2FgDb0YjAqkvO-obPuDhbqfrSOf1VrDlT" alt="Image" width="650" height="487" loading="lazy"></p>
<p>Click on publish. Visual Studio will start publishing your application. If there are no build errors, then your application will be published successfully to the folder you have mentioned.</p>
<p>After the publishing is successful, we will move on to configure IIS.</p>
<h3 id="heading-configuring-iis">Configuring IIS</h3>
<p>Open IIS and right click on Sites &gt;&gt; Add Web Site.</p>
<p>An “Add Website” pop up box will open. Here we need to furnish details in three fields</p>
<ol>
<li>Site name: Put any name of your choice. Here I will put “ankitsite”.</li>
<li>Physical Path: The path to the folder where you have published your application.</li>
<li>Host name: This is the name we put in browser to access our application. We will put <strong>ankitsite.com</strong> for this demo.</li>
</ol>
<p>Click on OK to create the website. Refer to the image below:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/gYvAyWLMlngmRpVgIDgAW0j7ZOcZHtVEDGyR" alt="Image" width="643" height="629" loading="lazy"></p>
<p>The next step is to configure the “Application Pool” for our site. The application pool name will be same as the “Site name” we provided in the last step. Therefore, in this case the application pool name will be “ankitsite”.</p>
<p>Click to “Application Pools” from the left panel and double click on the pool “ankitsite”. It will open an “edit application pool” window. Select “No Managed Code” from the .NET CLR version dropdown. Refer to the image below:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/6Vzduhtg1YwMvYQUBDZuX6VSaHiSWhwa7Ako" alt="Image" width="443" height="409" loading="lazy"></p>
<p>Here is the whole process of configuring IIS explained in a gif image.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/dNoMZnLndfBk7e1Elct13SB0ovTqhMUb136h" alt="Image" width="650" height="447" loading="lazy"></p>
<h3 id="heading-configuring-the-dns-host">Configuring the DNS host</h3>
<p>The last step is to configure our DNS host file.</p>
<p>Navigate to the <strong>C:\Windows\System32\drivers\etc</strong> path in your machine and open the “hosts” file using any text editor.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/R9jJHC5-mkBuAYjO0Lk17QlzeFxSVyFNFBiQ" alt="Image" width="550" height="236" loading="lazy"></p>
<p>We need to add the hostname that we provided in IIS against the localhost IP address. Refer to the image below:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/U1dOrUOXwAcK6EhDnbSOJJja7ex9n7QBrTL-" alt="Image" width="800" height="426" loading="lazy"></p>
<p>And now we have successfully hosted a Blazor application on IIS.</p>
<h3 id="heading-execution-demo">Execution Demo</h3>
<p>Open any browser on your machine and enter the hostname you have configured. You can see that the application will open in the browser window.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/Vcb7-n8EFzMdE9H9MWDQZU8-seObr43fOGPs" alt="Image" width="650" height="357" loading="lazy"></p>
<h3 id="heading-troubleshooting-common-hosting-issues">Troubleshooting common hosting issues</h3>
<p>In this section, we will look into some of the common problems that you can face while hosting a Blazor application.</p>
<ol>
<li>You are unable to open the website and get a DNS not found error</li>
</ol>
<p>Check if the hostname is configured correctly in the host file. Make sure that your machine is not connected to any VPN server. Also, if you are using any Web proxy, then disable it.</p>
<ol start="2">
<li>HTTP Error 500.19 — Internal Server Error — The requested page cannot be accessed because the related configuration data for the page is invalid.</li>
</ol>
<p>This error message is clear. The publish folder is inaccessible because of insufficient permissions. Grant Read permission to the IIS_IUSRS group on the publish folder so that it can access the Web.config file.</p>
<ol start="3">
<li>The website is loading but data is not getting populated, and you get a 500 Internal server error</li>
</ol>
<p>Make sure that your connection string is in the correct format. The user id that you have specified in your connection string should have db_datareader and db_datawriter permissions. If the issue persists, then provide the user with db_owner permission.</p>
<ol start="4">
<li>The data is not getting populated and you get an “operation not allowed” exception.</li>
</ol>
<p>This issue generally appears when you try to do a PUT, POST or DELETE operation in your web API. To mitigate this issue we need to alter the IIS setup configuration.</p>
<p>Navigate to Control Panel &gt;&gt; Turn Windows feature on or off. Then navigate to Internet Information Services &gt;&gt; World Wide Web Services &gt;&gt; Common HTTP Features and uncheck the “WebDAV Publishing” option and click ok. Refer to the image below:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/YA0t4fAfl53A7-LJfqT2ovgkXX1FQmH9PqpL" alt="Image" width="400" height="400" loading="lazy"></p>
<ol start="5">
<li>“Failed to load  : No ‘Access-Control-Allow-Origin’ header is present on the requested resource.</li>
</ol>
<p>The cause of this error is that the client and the server of the application are not on the same port. The browser will restrict the application to make web API calls due to same-origin policy. To resolve this issue, you need to enable Cross-Origin Requests (CORS) in your application. Please refer to the Microsoft documents on <a target="_blank" href="https://docs.microsoft.com/en-us/aspnet/core/security/cors?view=aspnetcore-2.1">Enable Cross-Origin Requests (CORS) in ASP.NET Core</a>.</p>
<p>When you republish the application, do not forget to refresh your website as well as the application pool in IIS.</p>
<h3 id="heading-conclusion">Conclusion</h3>
<p>In this article, we learned how to deploy a Blazor application on IIS on a Windows machine. We also learned how to resolve some of the common hosting issues while deploying a Blazor application.</p>
<p>Get my book <a target="_blank" href="https://www.amazon.com/Blazor-Quick-Start-Guide-applications/dp/178934414X/ref=sr_1_1?ie=UTF8&amp;qid=1542438251&amp;sr=8-1&amp;keywords=Blazor-Quick-Start-Guide">Blazor Quick Start Guide</a> to learn more about Blazor.</p>
<p>You can check out my other articles on Blazor <a target="_blank" href="http://ankitsharmablogs.com/category/blazor/">here</a>.</p>
<p>You can also find this article at <a target="_blank" href="https://www.c-sharpcorner.com/article/deploying-a-blazor-application-on-iis/">C# Corner</a>.</p>
<h3 id="heading-see-also">See Also</h3>
<ul>
<li><a target="_blank" href="http://ankitsharmablogs.com/asp-net-core-getting-started-with-blazor/">ASP.NET Core — Getting Started With Blazor</a></li>
<li><a target="_blank" href="http://ankitsharmablogs.com/asp-net-core-crud-using-blazor-and-entity-framework-core/">ASP.NET Core — CRUD Using Blazor And Entity Framework Core</a></li>
<li><a target="_blank" href="http://ankitsharmablogs.com/asp-net-core-crud-using-angular-5-and-entity-framework-core/">ASP.NET Core — CRUD Using Angular 5 And Entity Framework Core</a></li>
<li><a target="_blank" href="http://ankitsharmablogs.com/asp-net-core-crud-with-react-js-and-entity-framework-core/">ASP.NET Core — CRUD With React.js And Entity Framework Core</a></li>
<li><a target="_blank" href="http://ankitsharmablogs.com/asp-net-core-using-highcharts-with-angular-5/">ASP.NET Core — Using Highcharts With Angular 5</a></li>
</ul>
<p>Originally published at <a target="_blank" href="https://ankitsharmablogs.com/">https://ankitsharmablogs.com/</a></p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
