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

Get the Reference or Instance of a Component in ASP.NET Core Blazor

o capture a component reference in Blazor, use the @ref directive attribute. The value of the attribute should match the name of a settable field with the same type as the referenced component.

<MyLoginDialog @ref="loginDialog" ... />

@code {
    MyLoginDialog loginDialog;

    void OnSomething()
    {
        loginDialog.Show();
    }
}

References
https://docs.microsoft.com/en-us/dotnet/architecture/blazor-for-web-forms-developers/components#capture-component-references
https://www.syncfusion.com/faq/blazor/components/how-do-i-get-the-reference-or-instance-of-a-component

Two-way Binding in Blazor Component

We need to tell Blazor that the consuming page wants to use two-way binding.To use two-way binding on a parameter simply prefix the HTML attribute with the text @bind-. This tells Blazor it should not only push changes to the component, but should also observe the component for any changes and update its own state accordingly.

Two-way binding in Blazor uses a naming convention. If we want to bind to a property named SomeProperty, then we need an event call-back named SomeProperyChanged. This call-back must be invoked any time the component updates SomeProperty.

SecondComponent.razor

<h3>SecondComponent</h3>

<button @onclick="Callback">Increment</button>

@code {

    [Parameter]
    public int CounterValue { get; set; }

    [Parameter]
    public EventCallback<int> CounterValueChanged { get; set; }

    private async Task Callback()
    {
        if (CounterValue >= 20)
        {
    // reset counter
            CounterValue = 0;
        }
        else
        {
            CounterValue++;
        }

    // fire event
        await CounterValueChanged.InvokeAsync(CounterValue);
    }

}

Counter.razor

@page "/counter"

<SecondComponent @bind-CounterValue="counter"></SecondComponent>

<p>@counter</p>

@code
{
    private int counter = 2;
}

References
https://docs.microsoft.com/en-us/aspnet/core/blazor/components/data-binding?view=aspnetcore-6.0#binding-with-component-parameters
https://blazor-university.com/components/two-way-binding/
https://stackoverflow.com/questions/57932850/how-to-make-two-way-binding-on-blazor-component