StateHasChanged() vs InvokeAsync(StateHasChanged) in Blazor WebAssembly

I have tried calling StateHasChanged() – instead of InvokeAsync(StateHasChanged) – in a Timer’s Elapsed event, and it works as expected

That must have been on WebAssembly. When you try that on Blazor Serverside I would expect an exception. StateHasChanged() checks if it runs on the right thread.

The core issue is that the rendering and calling StateHasChanged both have to happen on the main (UI) thread. Actually that is “on the SynchronizationContext” but for all intents and purposes you can think of it as being a single-thread, just as in WinForms, WPF and other GUIs). The virtual DOM is not thread-safe.

The main Blazor life-cycle events (OnInit, AfterRender, ButtonClick) are all executed on that special thread so in the rare case that you need StateHasChanged() there it can be called without InvokeAsync().

A Timer is different, it is an “external event” so you can’t be sure it will execute on the correct thread. InvokeAsync() delegates the work to Blazor’s SynchronizationContext that will ensure it does run on the main thread.

But Blazor WebAssembly only has 1 thread so for the time being external events always run on the main thread too. That means that when you get this Invoke pattern wrong you won’t notice anything. Until one day, when Blazor Wasm finally gets real threads, your code will fail. As is the case with your Timer experiment.

What is “Blazor’s synchronization context”?

In .net a synchronization context determines what happens with (after) await. Different platforms have different settings, the Blazor synccontext is a lot like that of WinForms and WPF. Mainly, the default is .ConfigureAwait(true): resume on the same thread/context.

I sometimes see .ConfigureAwait(false) in toplevel Blazor Wasm code. That too will blow up when we get real threads there. It is fine to use in services called from Blazor, but not for the toplevel methods.

And finally, await InvokeAsync(StateHasChanged) or await InvokeAsync(() => StateHasChanged()) is just about lambda’s in C#, nothing to do with Blazor. The first short form is a little more efficient.

I also sometimes see InvokeAsync() called without await

That will work. It probably is better than the other option: making the calling method (like the Timer’s OnTick) an async void. So do use this from a synchronous code path.

Reference

https://stackoverflow.com/questions/65230621/statehaschanged-vs-invokeasyncstatehaschanged-in-blazor

400 vs 422 response in post action

There are three possible types of client errors on API calls that receive request bodies:

Sending invalid JSON will result in a 400 Bad Request response:

HTTP/1.1 400 Bad Request
Content-Length: 35
{"message":"Problems parsing JSON"}

Sending the wrong type of JSON values will result in a 400 Bad Request response:

HTTP/1.1 400 Bad Request
Content-Length: 40

{"message":"Body should be a JSON object"}

Sending invalid fields will result in a 422 Unprocessable Entity response:

HTTP/1.1 422 Unprocessable Entity
Content-Length: 149

{
  "message": "Validation Failed",
  "errors": [
    {
      "resource": "Issue",
      "field": "title",
      "code": "missing_field"
    }
  ]
}

Reference

https://stackoverflow.com/questions/16133923/400-vs-422-response-to-post-of-data

Blazor WebAssembly and Antiforgery token

EditForm comes with built-in anti-forgery token support. Blazor automatically secures the EditForm instances, saving you the hassle of explicitly handling CSRF protection.

Blazor WebAssembly apps run entirely in the browser and do not have a server-side processing pipeline where you would typically configure a middleware such as app.UseAntiforgery(). If your Blazor WebAssembly app interacts with server-side APIs, you should manage anti-forgery at the API level. However, if you already use token-based authentication to secure communication, anti-forgery tokens are generally not necessary. Token-based authentication, by its nature, mitigates the risks associated with CSRF, making additional anti-forgery tokens redundant.

Reference

https://learn.microsoft.com/en-us/xandr/digital-platform-api/token-based-api-authentication

Attribute Routing in ASP.NET Web API 2

Routing is how Web API matches a URI to an action. Web API 2 supports a new type of routing, called attribute routing. As the name implies, attribute routing uses attributes to define routes. Attribute routing gives you more control over the URIs in your web API. For example, you can easily create URIs that describe hierarchies of resources.

The earlier style of routing, called convention-based routing, is still fully supported. In fact, you can combine both techniques in the same project.

One advantage of convention-based routing is that templates are defined in a single place, and the routing rules are applied consistently across all controllers. Unfortunately, convention-based routing makes it hard to support certain URI patterns that are common in RESTful APIs. For example, resources often contain child resources: Customers have orders, movies have actors, books have authors, and so forth. It’s natural to create URIs that reflect these relations:

/customers/1/orders

This type of URI is difficult to create using convention-based routing. Although it can be done, the results don’t scale well if you have many controllers or resource types.

With attribute routing, it’s trivial to define a route for this URI. You simply add an attribute to the controller action:

[Route("customers/{customerId}/orders")]
public IEnumerable<Order> GetOrdersByCustomer(int customerId) { ... }

Attribute routing for REST APIs

REST APIs should use attribute routing to model the app’s functionality as a set of resources where operations are represented by HTTP verbs.

Attribute routing uses a set of attributes to map actions directly to route templates. The following code is typical for a REST API and is used in the next sample:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers();

var app = builder.Build();

app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();

app.Run();

In the preceding code, MapControllers is called to map attribute routed controllers.

In the following example:

  • HomeController matches a set of URLs similar to what the default conventional route {controller=Home}/{action=Index}/{id?} matches.
public class HomeController : Controller
{
    [Route("")]
    [Route("Home")]
    [Route("Home/Index")]
    [Route("Home/Index/{id?}")]
    public IActionResult Index(int? id)
    {
        return ControllerContext.MyDisplayRouteInfo(id);
    }

    [Route("Home/About")]
    [Route("Home/About/{id?}")]
    public IActionResult About(int? id)
    {
        return ControllerContext.MyDisplayRouteInfo(id);
    }
}

Read more here;

https://learn.microsoft.com/en-us/aspnet/core/mvc/controllers/routing?view=aspnetcore-9.0

https://learn.microsoft.com/en-us/aspnet/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api-2

Cloud computing

Cloud computing is the on-demand delivery of IT resources over a network. In traditional data centers, compute and storage resources used to be allocated manually by a dedicated IT team. In the cloud, this process is fully automated, leading to increased agility and significant cost savings.

Types of clouds

Cloud types vary depending on who owns or operates them. It is also possible to use more than one cloud at a time in a hybrid or multi-cloud architecture.

Public cloud

Public clouds are owned and managed by a cloud service provider. All resources are shared between multiple tenants. Even though the public cloud market is dominated by three major players, hundreds of smaller public cloud providers exist all over the world and run their public cloud infrastructure on Ubuntu.

More about public clouds ›

Private cloud

A private cloud is owned by an organization or an individual. All resources are exclusively dedicated to a single entity or a service. It runs on the organization’s premises or in an external data center. It is managed by the organization’s operations team or a managed service provider.

More about private clouds ›

Managed cloud

Managed clouds are private clouds that are fully managed by a third-party organisation (aka managed service provider). The customer provides the hardware, but cloud operations and maintenance tasks are outsourced. The cloud can either run on the organisation’s premises or in the managed service provider’s data centre.

More about managed clouds ›

Micro cloud

Micro clouds are a new class of infrastructure for on-demand computing at the edge. They differ from the internet-of-things (IoT), which uses thousands of single machines or sensors to gather data, yet they perform computing tasks. Micro clouds reuse proven cloud primitives but with the unattended, autonomous and clustering features that resolve typical edge computing challenges.

More about micro clouds ›

Hybrid cloud

Hybrid cloud is a cloud computing architecture that consists of at least one public cloud, at least one private cloud and a hybrid cloud manager (HCM). It is one of the most popular trends in the IT industry, adopted by 82% of IT leaders, according to the Cisco 2022 Global Hybrid Cloud Trends Report.

More about hybrid clouds ›

Multi-cloud

Multi-cloud (also referred to as multi cloud or multicloud) is a concept that refers to using multiple clouds from more than one cloud service provider at the same time. The term is also used to refer to the simultaneous running of bare metal, virtualised and containerised workloads.

More about multi-cloud ›

Cloud computing models

Cloud computing services are usually available to end users in the form of three primary models. Those include infrastructure-as-a-service (IaaS), platform-as-a-service (PaaS) and software-as-a-service (SaaS). Some more specific use cases exist too, such as container-as-a-service (CaaS). However, in essence, they are a subset of the main three.

IaaS

In the IaaS model, you provision resources. Those include the number of virtual CPUs (vCPUs), the amount of RAM, storage, etc. They come in the form of VMs or containers with a pre-installed operating system (OS). You manage everything up from there. IaaS is the most common cloud computing model as it allows for more freedom.

PaaS

In the PaaS model, you provision workloads. While you are still responsible for delivering application code and data management, the PaaS platform takes care of scheduling resources (usually containers) and manages them, including the OS, middleware and runtime. The PaaS model has never been widely adopted due to its overall complexity.

SaaS

In the SaaS model, you provision applications. They are deployed from pre-defined templates and can be configured according to your needs. Everything is managed by the cloud provider. Interest in the SaaS model is constantly increasing as it allows for full automation from the ground up.

 Legacy data centreIaaSPaasSaas
ApplicationsYou manageYou manageYou manageCloud provider
DataYou manageYou manageYou manageCloud provider
RuntimeYou manageYou manageCloud providerCloud provider
MiddlewareYou manageYou manageCloud providerCloud provider
O/SYou manageYou manageCloud providerCloud provider
VirtualisationYou manageCloud providerCloud providerCloud provider
ServersYou manageCloud providerCloud providerCloud provider
StorageYou manageCloud providerCloud providerCloud provider
NetworkingYou manageCloud providerCloud providerCloud provider

Reference

https://ubuntu.com/cloud/cloud-computing