Develop a Blazor Web-Assembly App with Azure Function and Deploy as a Azure Static Apps

During the past years, Microsoft introduced different web-based frameworks related to web development, like Asp.Net MVC, Asp.Net Web Page, and, most recently, Asp.Net Core. With the introduction of each new framework, there are a few predictions related to the discontinuation of the Asp.Net Web Forms as an outdated framework. But still, now, developers continue to work with the Asp.Net Web Forms as it is much simpler, more stable, and more productive than the other framework. Still today, around half a million web developers used Asp.Net WebForms. In 2018, Microsoft introduced a new web-based framework called Blazor. 

What is Web Assembly?

WebAssembly is treated as a low-level-based assembly language for any platform. Therefore, Web Assembly is also known as a web standard. With the help of WebAssembly, we can execute the web page's code at the same speed, just like native machine code. Generally, the high-level language used to develop the web application is converted into WebAssembly and then runs like a native code speed in the browser. Due to this breaking achievement in web development, we can now use conventional server-side languages like C# and F# to develop any web application which can be run into the browser directly.

Nowadays, all the modern browser versions are supported the WebAssembly. But the question is, what will happen if someone uses the old version of browsers or old phones? WebAssembly will take care of this scenario by itself. In the case of old browsers, WebAssembly internally fallback to JavaScript and run the application without any hitch. WebAssembly is also open-source, so anybody can easily debug the code into the web platform. WebAssembly is generally abbreviated as wasm. Also, most importantly, Blazor does not require installing the .Net framework in the client machine to run the WebAssembly.

What is Web Assembly? 

In the case of Blazor, we can use the Blazor WebAssembly App to run the application on the client side. As we know, WebAssembly or wasm contains the instruction in a binary format that the browsers can execute. In the case of Blazor, this conversion means from high-level language to binary format instruction is done with the help of Mono runtime. WebAssembly is represented as a textual assembly language that supports compact binary format data. With this help, it provides near-native fast performance with fast download of the application. With the help of WebAssembly, we can also develop a progressive web application that can be downloaded and run offline at the user's end. Below is the list of browsers with a version of the WebAssembly.

About Blazor Web Assembly

Microsoft introduced Blazor WebAssembly Hosting Model in May 2020. Blazor WebAssembly or Blazor – WASM-based application mainly runs on the client-side browser with the help of WebAssembly-based .NET runtime. While we access the web application in the browser, the Blazor app, its related dependencies, and the .Net runtime libraries are downloaded in the browser at the client side machine. The application is always executed on the browser using the UI thread and handles the event-related processes. In the Blazor Web-Assembly application, application assets like CSS, js, image files, etc., are considered static files in the web server part. Therefore, we can create the Blazor WebAssembly app in two different ways. If we make the application without the support of the Asp.Net Core back-end app for its server-type files, then that application is treated as a standalone Blazor WebAssembly app. On the other hand, when we create the application with the back-end app options to serve its server-side files, it is treated as a hosted Blazor WebAssembly app. 

Blazor Web Assembly

In the case of a Blazor WebAssembly app, we can develop it as a Progressive Web App (PWA) to use the support of the modern browser API. So that we can enable different functionality of a native client app like offline work, running the application on its separate window, enabling push notifications, and automatic version updates as a background process. With the help of Blazor WebAssembly, we can use the full-stack web development process with .Net Core. In the process, we can use the same code between the client and server application and perform integration with MVC and Razor pages. While we hosted the client app on a server, the client app can communicate with the back-end server application with the help of different protocols or messaging frameworks like Web API, SignalR, and gRPC-Web.

We can achieve several benefits while we use the Blazor WebAssembly (wasm) hosting model like –

  • In the case of Blazor WebAssembly, there is no dependency once the app is downloaded into the client machine from the server. So, if the server goes offline, the app will continue working.
  • The Asp.Net Core web server is not necessarily required to host the application. Instead, we can use the serverless deployment mechanism like CDN to host the application.
  • We can use the client's resources and capabilities fully.
  • Despite the above benefits, the Blazor WebAssembly app also has some limitations like – 
  • The application is dependent on the capability of the browser.
  • For the first time, when the application is opened in the client browser, it downloads the entire app-related resources along with runtime libraries and dependencies. 
  • So, based on the application size, it can take longer to load the application for the first time.

As the application entirely depends on the client's machine, proper software and hardware configuration are required for the client's machine.

Develop the Blazor Web Assembly App 

Step 1. First, open Microsoft Visual Studio 2022 and click Create a New Project.

Step 2. Now select the Blazor WebAssembly App option and click on the Next Button.

Develop Blazor Web Assembly App

Step 3. In the Next window, provide the Project name and click the Next Button.

Develop Blazor Web Assembly App

Step 4. Now, select the Framework version as .Net7 and then click on the create button.

Develop Blazor Web Assembly App

Step 5. For the client app, we will create one Product related shopping cart-related UI. 

Step 6. For that purpose, Add the new class called Product.cs under the blazor_wasm_static_app.Shared projects.

public class Product
{
    public string ProductCode { get; set; }
    public string ProductName { get; set; }
    public string Description { get; set; }
    public string Manufacturer { get; set; }
    public string ProductImage { get; set; }
    public decimal Price { get; set; }
}

Step 7. Now, add a products.json file under the wwwroot data folder, and in that particular file, add some JSON formatted data based on the Product model class.

Step 8. Now, select the Pages folder and add a new component called CardComponent.razor and add the below code into that file – 

<div class="card border-0 mb-3">
    <div class="h-100">
        <img class="card-img" src="@ProductImage" alt="Card image cap" height="300px" width="150px">
    </div>
    <div class="card-body p-3">
        <div class="d-flex align-items-center info-space bg-dark">
            <div>
                <center><span class="text-white" style="font-size:larger;">@ProductName</span></center>
            </div>
        </div>
        <div class="description-space" style="color:blue;">
            <p class="text-muted text-monospace">
                <medium>@Description</medium>
            </p>
        </div>
        <div class="card-header font-weight-bold">
            Manufactured By : <span>@Manufacturer</span>
        </div>
        <div class="card-header font-weight-bold">
            Price : <span>&#8377; @Price</span>
        </div>
    </div>
</div>

@code
{

    [Parameter]
    public RenderFragment ChildContent { get; set; }

    [Parameter(CaptureUnmatchedValues = true)]
    public Dictionary<string, object> InputAttributes { get; set; }


    [Parameter]
    public string ProductCode { get; set; }
    [Parameter]
    public string ProductName { get; set; }
    [Parameter]
    public string ProductImage { get; set; }
    [Parameter]
    public string Description { get; set; }
    [Parameter]
    public string Manufacturer { get; set; }
    [Parameter]
    public decimal Price { get; set; }
}

Step 9.  Now open the Index.razor file and replace the code of that particular file with the below code – 

@page "/"
@using blazor_wasm_static_app.Shared.Extensions;
@using blazor_wasm_static_app.Shared.Models;
@inject HttpClient Http;
<link href="css/site.css" rel="stylesheet" />

<PageTitle>Shopping Cart</PageTitle>

<h1>Blazor WebAssembly Demo - Shapping Cart</h1>

<div class="row">
    @foreach (var product in ProductList)
    {
        <div class="col-xs-12 col-sm-6 col-md-4 col-lg-3">
            <CardComponent ProductCode="@product.ProductCode"
                       ProductName="@product.ProductName"
                       Description="@product.Description"
                       Manufacturer="@product.Manufacturer"
                       ProductImage="@product.ProductImage"
                       Price="@product.Price" />
        </div>

    }
</div>

@code
{
    public List<Product> ProductList { get; set; } = new List<Product>();

    protected override async Task OnInitializedAsync()
    {
        await GetProducts();
    }

    private async Task GetProducts()
    {
        List<Product> products = await Http.GetFromJsonAsync<List<Product>>("data/products.json");
        ProductList = products.Shuffle<Product>().ToList();
    }
}

Step 10. Now, open the Program.cs file and add the below code –

using blazor_wasm_static_app;
using blazor_wasm_static_app.Client;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;

var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("#app");
builder.RootComponents.Add<HeadOutlet>("head::after");

var baseAddress = builder.HostEnvironment.BaseAddress;

builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });

await builder. Build().RunAsync();

Step 11:  Now, run the application and check the output in the browser.

Develop Blazor Web Assembly App

Develop Azure Function App for Server Side Code

Step 1. Now, select the solution file and click on Add New Project Option.

Step 2. Now select the Azure Function option and click on the Next Button.

Develop Azure Function App for Server Side Code

Step 3. Now Provide the project name as blazor_wasm_static.Function and then click on the next button.

Step 4. Now, Click on the Create Button.

Step 5. Now, select the project and click on Add  New Azure Function options.

Develop Azure Function App for Server Side Code

Step 6. Provide the Function name GetProductsFunction and Click on Add Button.

Step 7. Select the Function trigger type as Http Trigger from the list and click Add Button.

Develop Azure Function App for Server Side Code

Step 8. Now open the newly added file and add the below code – 

public class GetProductsFunction
{
    private readonly ILogger _logger;

    public GetProductsFunction(ILoggerFactory loggerFactory)
    {
        _logger = loggerFactory.CreateLogger<GetProductsFunction>();
    }

    [Function("GetProducts")]
    public async Task<List<Product>> Run([HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequestData req)
    {
        string jsondata = @"[]";
        var result = JsonConvert.DeserializeObject<List<Product>>(jsondata);
        return result;
    }
}

Step 9. In the above example, under the jsondata property, copy and paste the contents of the products.json file mentioned in the previous section.

Step 10. Now open the Index.razor file and replace the code of GetProducts() method code as below – 

private async Task GetProducts()
{
    //List<Product> products = await Http.GetFromJsonAsync<List<Product>>("data/products.json");

    List<Product> products = await Http.GetFromJsonAsync<List<Product>>("/api/GetProducts");
    ProductList = products.Shuffle<Product>().ToList();
}

Step 11. Now run the Function Project and test the URL mentioned in the command prompt in the browser.   

Develop Azure Function App for Server Side Code

Deploy the Application as Azure Static Web App

Now, as both Blazor WebAssembly Projects and Azure Function projects are ready; we can deploy them within the Azure Static Web App. For this purpose, we need to first login into the Azure Portal and then needs to perform the below operations - 

Step 1. Search the Static Web App option by using the search textbox. 

Deploy the Application as Azure Static Web App

Step 2. Once we open the Static Web App Resource, click the Create Button to create the Azure Static Web App. 

Deploy the Application as Azure Static Web App

Step 3. Once we click the Create button, the below Static Web Apps related options are visible.

Deploy the Application as Azure Static Web App

Step 4. Once we need to provide all the marked details, then Choose Blazor in the Build Details section will appear below -

Deploy the Application as Azure Static Web App

Step 5. In the above section, we need to provide the below information -

  1. In the App Location box, if we need to mention the sub-folder name where client app related files exist. In our example, we need to provide the folder name as "blazor_wasm_static_app/Client".
  2. In the Api textbox, you need to provide the location path of the API project. For our example, it will be "blazor_wasm_static_app/Function/blazor_wasm_static.Function".

Step 6. Once we provide all the information, we can click the Preview Workflow File button to check the workflow file details.

Step 7. Now, Click the Review + Create Button to complete the Create Process.

Step 8. Once the Static web app is created, it takes 2-3 minutes to complete the application deployment. 

Step 9. Now check the output by clicking on the URL of the static web apps.

Deploy the Application as Azure Static Web App

Conclusion

So, in this article, we discuss the basic concept of the Blazor Web Assembly and how to deploy Blazor Web Assembly applications into Azure Static Web Apps. Any queries, suggestions, or feedback about this article are always welcome.


Similar Articles