Pages

Wednesday, December 9, 2020

MicroSoft Blazor

 Blazor

Today's web development, use both server-side (C#, Java,...) and client-side (JavaScript frameworks like Angular, React,..) technologies. 

Use C# both for server & client side development, that's Blazor. Blazor lets you build interactive web UIs using C# instead of JavaScript.

Blazor can run client-side C# code (or any type of code) directly in the browser, using WebAssembly. It runs in the same security sandbox as JavaScript frameworks like Angular, React, etc. 

WebAssembly is based on open web standards without using plug-ins or code transpilation. It works in all modern browsers including mobile browsers.  

There are 2 Blazor hosting models: Blazor WebAssembly (the client-side) and Blazor Server (the server) .

In Blazor WebAssembly model the application runs directly in the browser on WebAssembly.  So, everything the application needs (the compiled application code, it's dependencies and the .NET runtime) are downloaded to the browser. 

  • It can run entirely on the client without a connection to the server or interact with the server using web API calls or SignalR.
  • Cons : A connection to the server is not required. 
  • Work is offloaded from the server to the client (it using the client resources and capabilities).
  • No need a ASP.NET Core web server to host the application. 
  • Host the application on anywhere (server or cloud).
  • Pros : Very first request takes longer as the entire app (code downloaded to the client browser)
  • Client browser restriction
  • Need capable client hardware and software (to support WebAssembly) is required. 

In Blazor server model the application is executed on the server from within an ASP.NET Core application. 

  • Blazor embraces the SPA architecture which rewrites the same page dynamically in response to the user action. Since only the required UI change (difference) is applied to update the UI, the application feels faster and more responsive to the user.
  • Between the client and the server, a SignalR connection (a real-time messaging framework) is established. 
  • When an UI event occurs on the client (a button click), the information about the event is sent to the server over the SignalR connection.  The server handles the event, the required UI changes (not entire HTML, only difference) are send back again to the client over the established SignalR connection and merged into the DOM (that's the browser updates the UI). 
  • Pros : The app loads much faster as the download size is smaller than a Blazor WebAssembly app. 
  • It can take full advantage of server capabilities (running on the server)
  • Secure because the app's .NET/C# code isn't served to clients.
  • Cons : A complete ASP.NET Core server is required to host the application. 
  • Serverless deployment scenarios not possible.
  • An active connection to the server is always required.
  • Scalability can be challenging (server manage multiple client connections). To Overcome this scalability issue, by using Azure SignalR Service with a Blazor Server app, to scale a large number of concurrent SignalR connections.

Create Blazor Server & WebAssembly App Project

Using Visual Studio 2019, search "Blazor" 



Select "Blazor WebAssembly App" template to create a blazor application with client hosting model

Select "Blazor App Server" template to create a blazor application with server hosting model

Inspect Browser Developer tools -> Network tab
See what's downloaded from the server to the client, it downloads everything it needs to run offline in the browser without a connection to the server (the complied assembly code itself, the blazor webassembly dll (dotnet.wasm), all the dotnet dependent core dll's, lot of other things downloaded from the server)


Server App downloads minimal needs from the server to the client

Project Structure


Blazor Server App Project Structure

  • /Startup.cs
    • ConfigureServices - Configures the applications dependency injection services. AddServerSideBlazor() method adds Blazor server side services. 
    • Configure - Configures the app's request processing pipeline. 2 methods specific to Blazor
   app.UseEndpoints(endpoints =>
    {
endpoints.MapBlazorHub();
endpoints.MapFallbackToPage("/_Host");
    });
      • MapBlazorHub sets up the endpoint for the SignalR connection with the client browser. 

      • MapFallbackToPage
        • Accept request for a controller or a razor page, every other request is mapped to this page ("/_Host").
        • "/_Host" is the root page of the application and is specified by calling MapFallbackToPage("/_Host") method. 
        • "/_Host" file is specified in the pages folder  (Pages/_Host.cshtml)
  •  /Pages/_Host.cshtml
    • It is implemented as a razor page.
    • When a first request hits the application, this page is initially served. 
    • Navigate to other components within the application is rendered from within this host razor page
    • It also specifies where the root application component, App component (App.razor) must be rendered. 
<app>
  <component type="typeof(App)" render-mode="ServerPrerendered" />
</app>
    • It also loads the blazor.server.jsfile, which sets up the real-time SignalR connection between the server and the client browser.


  • /App.razor component 
    • Root component of the application. 
    • It uses the built-in Router component and sets up client-side routing. 
    • It intercepts browser navigation and renders the page that matches the requested address. 
    • The Router uses the Found property to display the content when a match is found. For example, if navigate to "http://localhost:32891/counter"
    • If not found, the NotFound property to display the message - "Sorry, there's...". For example, navigate to "http://localhost:32891/counter1"
    • Both found and not found sections uses a main layout file (Shared/MainLayout.razor) 
<Router AppAssembly="@typeof(Program).Assembly">
    <Found Context="routeData">
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
    </Found>
    <NotFound>
<LayoutView Layout="@typeof(MainLayout)">
    <p>Sorry, there's nothing at this address.</p>
</LayoutView>
    </NotFound>
</Router>

  • /Pages folder (/Counter.razor, /Error.cshtml, /FetchData.razor, /Index.razor)
    • Counter.razor component – Rendered when we navigate to the path /counter.
    • FetchData.razor component  – Rendered when we navigate to the path /fetchdata.
    • Index.razor component 
      • Rendered when we navigate to the root application URL.
      • Browse the root URL http://localhost:32891, the content from this component
      • How does our application know it has to render the Index.razor component, where we specify that using this @page directive.
      • "/" specifies when we navigate to this root URL we want this index razor component to be rendered 
    • Like other pages like the "/counter" render ttheis counter component.

    • Error.cshtml component
      • Rendered when an unhandled exception occurs in the blazor app.
      • It's automatically rendered when there is an unhandled exception or when we explicitly navigate to the path http://localhost:32891/error
  • /Shared folder
    • MainLayout component (MainLayout.razor) ,


      • The application's main layout component
      • All navigation menu is coming the <NavMenu /> component (NavMenu.razor).
      • @Body is our routed components (like index, counter, fetchdata) are reentered.
        • Navigate to the root URL (http://localhost:3289) the Index.razor component is rendered at this location (@Body)
    • NavMenu.razor component
      • Implements the navigation menu on the sidebar. 
      • NavLink component  ia renders navigation links. 
  • /_Imports.razor
    • Like the _ViewImports.cshtml file in an asp.net core MVC project. 
    • It contains the common namespaces so we do not have to include them in every razor component.
  • /Data folder - Contains code files related to the sample WeatherForecast service

Blazor WebAssembly App Project Structure

  • Program.cs 
    • The App component, which is the root component (App.razor) of the application, is specified in the Main method. 

  • wwwroot/index.html
    • Root page, when a first request hits the application, this page is initially served. 
    • It specifies where the root application component App.razor should be rendered. <app>Loading...</app> 
    • It also loads the blazor WebAssembly JavaScript file (_framework/blazor.webassembly.js).
      • It's responsible for downloading the compiled blazor application, it's dependencies and the .NET runtime
      • It also initializes the runtime to run the blazor app in the browser


  

ASP.NET core Razor or Blazor components

  • Everything in a Blazor application is a razor component. 
  • Components are the fundamental building blocks of a Blazor application. 
  • Components can be nested, reused, and shared across multiple projects.
  • Component files have the extension .razor
  • Component name must start with an uppercase character (like Counter.razor)
  • Components can be placed anywhere within a blazor project.
  • Counter.razor, combination of UI and C# code
  • C# code is in @code block, have more than one @code blocks

  • When the application is compiled, the HTML and C# code converted into a component class.
  • After the counter component is initially rendered and when the button is clicked IncrementCount() function called using the onclick attribute.
  • The click event is sent to the server over the SignalR connection.
  •  In response to the event, the component is regenerated, only the difference HTML is sent back to the client.
  • The c# code increments the currentCount variable value
  • In the HTML, to access the private variable currentCount value, use @ character.
  • Nested razor components

2 ways to separate HTML and C# code into their own files. It's easy to unit test and maintenance.

  • Partial files way

  • Base Class way


No comments:

Post a Comment