Call a Web API from ASP.NET Core Blazor Server

In Program.cs:

builder.Services.AddHttpClient();

Read String using GET method

@page "/"
@inject IHttpClientFactory ClientFactory

<PageTitle>Index</PageTitle>

<button @onclick="Button_Clicked">Call API</button>

@code {

    private async Task Button_Clicked()
    {
    // read string using GET method
        var request = new HttpRequestMessage(HttpMethod.Get, "http://localhost:5055/hello-world");
        var client = ClientFactory.CreateClient();
        var response = await client.SendAsync(request);

        if (response.IsSuccessStatusCode)
        {
            Console.WriteLine(await response.Content.ReadAsStringAsync());
        }
    }

}

Send and Read JSON using POST method

private async Task Button2_Clicked()
{
// send and read json using POST method
    var url = "http://localhost:5055/hello2";
    var person = new Person() {FirstName = "Mahmood", LastName = "Ramzani"};
    var json = JsonSerializer.Serialize(person);
    var data = new StringContent(json, Encoding.UTF8, "application/json");
    var client = ClientFactory.CreateClient();
    var response = await client.PostAsync(url, data);

    if (response.IsSuccessStatusCode)
    {
        Console.WriteLine(await response.Content.ReadAsStringAsync());
    }
}

 

References
https://docs.microsoft.com/en-us/aspnet/core/blazor/call-web-api?view=aspnetcore-6.0&pivots=server

JSON Parameter in ASP.NET MVC using [FromBody]

To force Web API to read a simple type from the request body, add the [FromBody] attribute to the parameter:

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}
[Route("hello2"), HttpPost]
public JsonResult Hello2([FromBody] Person person)
{
    string output = $@"Hello {person.FirstName} {person.LastName}";
    return Json(output);
}

When a parameter has [FromBody], Web API uses the Content-Type header to select a formatter. In this example, the content type is “application/json” and the request body is a raw JSON string (not a JSON object).

References
https://docs.microsoft.com/en-us/aspnet/web-api/overview/formats-and-model-binding/parameter-binding-in-aspnet-web-api

Return JSON Data from ASP.NET MVC Controllers

Send JSON Content welcome note based on user type

using System;  
using System.Collections.Generic;  
using System.Text;  
using System.Web.Mvc;  
using System.Web.Script.Serialization;  
using JsonResultDemo.Models;  
  
namespace JsonResultDemo.Controllers  
{  
    public class JsonDemoController : Controller  
    {  
        #region ActionControllers  
  
        /// <summary>  
        /// Welcome Note Message  
        /// </summary>  
        /// <returns>In a Json Format</returns>  
        public JsonResult WelcomeNote()  
        {  
            bool isAdmin = false;  
            //TODO: Check the user if it is admin or normal user, (true-Admin, false- Normal user)  
            string output = isAdmin ? "Welcome to the Admin User" : "Welcome to the User";  
  
            return Json(output, JsonRequestBehavior.AllowGet);  
        }  
     }  
}

Get the list of users in JSON Format

/// <summary>  
/// Update the user details  
/// </summary>  
/// <param name="usersJson">users list in JSON Format</param>  
/// <returns></returns>  
[HttpPost]  
public JsonResult UpdateUsersDetail(string usersJson)  
{  
    var js = new JavaScriptSerializer();  
    UserModel[] user = js.Deserialize<UserModel[]>(usersJson);  
  
    //TODO: user now contains the details, you can do required operations  
    return Json("User Details are updated");  
}

References
https://www.c-sharpcorner.com/UploadFile/2ed7ae/jsonresult-type-in-mvc/
https://stackoverflow.com/questions/227624/asp-net-mvc-controller-actions-that-return-json-or-partial-html

Creating a Blazor Layout

Any content you intend to act as a layout template for pages must descend from the LayoutComponentBaseclass. To indicate where you want the content of your page to appear you simply output the contents of the Body property.

@inherits LayoutComponentBase
<div class="main">
  <header>
    <h1>This is the header</h1>
  </header>
  <div class="content">
    @Body
  </div>
  <footer>
    This is the footer
  </footer>
</div>

References
https://blazor-university.com/layouts/creating-a-blazor-layout/
https://blazor-university.com/layouts/using-layouts/

Component Virtualization in ASP.NET Core Blazor

Virtualization is a technique that helps you to process and render only the items that are currently visible on the page (in the content viewport). We can use this technique when dealing with large amounts of data, where processing all the data and displaying the result will take time.

<div style="height:400px; overflow-y:scroll">
    <Virtualize Items="@allBooks">
        <BookSummary @key="book.BookId" Details="@book.Summary" />
    </Virtualize>
</div
<Virtualize Context="employee" ItemsProvider="@LoadEmployees">
    <p>
        @employee.FirstName @employee.LastName has the 
        job title of @employee.JobTitle.
    </p>
</Virtualize>
<Virtualize Context="employee" Items="@employees" ItemSize="25">
    ...
</Virtualize>
<Virtualize Context="employee" Items="@employees" OverscanCount="4">
    ...
</Virtualize>

References
https://docs.microsoft.com/en-us/aspnet/core/blazor/components/virtualization?view=aspnetcore-6.0
https://www.syncfusion.com/blogs/post/7-features-of-blazor-that-make-it-an-outstanding-framework-for-web-development.aspx/amp
https://www.syncfusion.com/blogs/post/asp-net-core-blazor-component-virtualization-in-net-5.aspx

Cancel Background long-running Tasks when a user navigates to another page in Blazor

@page "/State"
@implements IDisposable

<h3>State</h3>

<p>@output</p>

@code {
    private string output = "";
    private CancellationTokenSource cts = new();
    
    protected override async Task OnInitializedAsync()
    {
        while (!cts.IsCancellationRequested)
        {
            await Task.Delay(1000);
            var rnd = new Random();
            output = rnd.Next(1, 50).ToString();
            StateHasChanged();
        }
        
        // cts.Token.ThrowIfCancellationRequested();
    }
    
    public void Dispose()
    {
        cts.Cancel();
        cts.Dispose();
    }
}

References
https://docs.microsoft.com/en-us/aspnet/core/blazor/components/lifecycle?view=aspnetcore-6.0#cancelable-background-work
https://www.syncfusion.com/faq/blazor/web-api/how-do-i-cancel-background-long-running-tasks-when-a-user-navigates-to-another-page-in-blazor

Refresh a Blazor Component with StateHasChanged

@page "/State"
<h3>State</h3>

<p>@output</p>

@code {
    private string output = "";
    
    protected override async Task OnInitializedAsync()
    {
        while (true)
        {
            await Task.Delay(1000);
            var rnd = new Random();
            output = rnd.Next(1, 50).ToString();
            StateHasChanged();
        }
    }
}

References
https://www.techiediaries.com/refresh-blazor-component-statehaschanged-invokeasync/
https://docs.microsoft.com/en-us/aspnet/core/blazor/components/lifecycle?view=aspnetcore-6.0#state-changes-statehaschanged

Optimizing Blazor performance using the @key directive

The @key directive is important when creating components dynamically by iterating list/IEnumerable. Adding the @key will ensure proper change detection and UI update in the collection of components.

<ul class="mt-5">
    @foreach (var person in People)
    {
        <li @key="person.Id">@person.Id, @person.Name</li>
    }
</ul>

Tip: Always use @key for components that are generated in a loop at runtime.

References
https://blazor-university.com/components/render-trees/optimising-using-key/
https://www.meziantou.net/optimizing-blazor-performance-using-the-key-directive.htm
https://www.syncfusion.com/faq/blazor/components/what-is-the-use-of-key-property