Blazor excited me when it first emerged with the promise of unifying the codebase from the UI to the API. Now with .NET 5 bringing Blazor to maturity for real-world projects, I’m ready to dive in. So, is Blazor ready? Are you ready?
Based on our experience building those web applications with React, I want to outline how well Blazor fits in these key areas:
- SPA Design Pattern
- UI Models and using the API
- Validation and Forms
- Logging and Analytics
SPA Design Pattern
React and Redux
Redux and React have become staples when building a SPA. The predictable state container that Redux provides and the ability to manage that state via actions and reducers is paramount. Redux was specifically designed to work well with React binding the UI as functions of your state, updating it in response to actions.
Fluxor for Blazor
With Blazor, the same design pattern is preferred. Flux (from Facebook) is the design pattern Redux is based on. That pattern is provided by Fluxor for the Blazor application. The concepts of a managed Store with Reducers, Dispatchers, and Actions all exist in C# without the need for a lot of code.
Also, Fluxor includes a Redux DevTools browser extension (Chrome & Edge) that eases debugging by providing access to the current state and the prior state in a timeline navigation. This is a great tool to see what is happening when actions are occurring in the UI.
Below is some sample code of a simple Blazor page using state with UI actions and dispatcher.
- Fluxor for Blazor – https://github.com/mrpmorris/Fluxor
UI Models and using the API
With Fluxor, Blazor can reach parity with React/Redux. But the application’s state will need to be comprised of objects for the various pages. Besides, the actions will be interacting with the API via routes. Both can be accomplished by hand-coding C# classes for the models and mapping to the API endpoints. In practice, there is a better way, code-generation.
For React SPA’s, it is common to use the NSwag tools to generate DTO’s and actions from the API based on the OpenAPI spec. This is done with PostBuild actions for the API .Net Core project. With a React solution, these will be generating TypeScript. Code generation applies for Blazor also, but it will create C# classes.
Example PostBuild actions
The first command creates the swagger.json OpenAPI spec from the API’s controllers. The second creates a C# client with a DTO class and a “proxy” class using HttpClient to execute calls to all of the API routes with appropriate request and response types. This is great for React and Blazor since the actual UI code can now reference the DTO’s in the state store and with the needed actions.
Amplify Your Value With Custom Product Development
The world has changed, with digital presenting unprecedented opportunities for new revenue streams for companies across industries. How you can take advantage of and exploit your unique offerings to your competitive advantage by exploring custom development?
One downside to the generated DTO’s above is these duplicate existing models in the API (solution domain). Unlike React using TypeScript, Blazor is using native C# .Net code. This brings the promise of unifying the codebase to reality! Now, the NSwag code generation can be tweaked to not create DTO classes (just create the HttpClient proxy) and instead reference a domain model class library containing the same model classes used by the API.
Validation and Forms
Now that the Blazor UI project uses the same domain models as the API, the UI can also leverage common business and validation logic. This can be done simply with DataAnnotations with the domain models. With React, the similar client-side validation would require separate and redundant code. Yay, more code unification!
Example model with DataAnnotations
Blazor also expands on the model and validation usage with Forms. Using the form components instead of simple UI components, validation will be automatically performed and results displayed in a summary component. The below example shows the same simple Index page using a form.
Index.razor without form
Index.razor using form
- Blazor forms and validation – https://docs.microsoft.com/en-us/aspnet/core/blazor/forms-validation?view=aspnetcore-5.0
Both React and Blazor are component-oriented UI frameworks, meaning you can compose a page of components. The components can be simple, complex, out-of-the-box, 3rd party, or custom. This is great for reuse and consistency across a single application or beyond an organization.
Blazor is younger than React and some other SPA UI solutions. However, it is maturing rapidly with many 3rd parties provided component libraries—these range from smaller, open-source collections to large, commercial offerings. Regardless of the application requirements, there are likely Blazor components to be found for use that eliminate the need to create your own.
- DevExpress Blazor Components
- Radzen Blazor Components
- Telerik UI for Blazor
Custom Components and Libraries:
Blazor components can be created from scratch and can encapsulate other components. These use the same razor syntax and C# code we’re used to. These can also be packages in a library for sharing and/or published via nuget if needed.
So far, I’ve focused on UI concerns since Blazor is all about the UI. However, as a solutions architect, I would be remiss if I didn’t address some of the important cross-cutting concerns. The biggest would be security. Security for a SPA has become somewhat standard (like React/Redux/API usage). This typical approach utilizes OpenID Connect (OIDC), which is based on the OAuth2.0 protocol.
Authorization can be demanded for the entire Blazor application or on a page level. Both cases apply the @attribute [Authorize] as shown below.
Application-level authorization via _Imports.razor
Page-level authorization via Index.razor
Blazor includes the Authentication library, which provides token-based authentication based on JSON Web Tokens (JWTs). The authentication library provides seamless authentication with ASP.NET Core backends and integrates ASP.NET Core Identity with API authorization.
Security is a larger topic than this post allows. However, Blazor is well-positioned to support the needs of a SPA backend authentication and UI authorization. See the reference below for more details.
- Blazor Authentication Library – https://docs.microsoft.com/en-us/aspnet/core/blazor/security/webassembly/?view=aspnetcore-5.0
- Secure an ASP.NET Core Blazor WebAssembly – https://docs.microsoft.com/en-us/aspnet/core/blazor/security/webassembly/standalone-with-authentication-library?view=aspnetcore-5.0&tabs=visual-studio
Logging and Analytics
As with the rest of the application, the Blazor UI can benefit from including tracing for information and exceptions after deployment. In addition, the UI will likely depend on some usage analysis. Happily, these concerns have solutions.
In my recent React SPA experience, Application Insights was used in the front-end to provide means for tracing information and exceptions initiated within the TypeScript code. The same can be done with the Blazor application via the nuget package listed below. Interestingly, at this time, this is provided by a 3rd party, not Microsoft. This may change in the future. However, as it exists, the package does provide the needed abilities for tracking traces, exceptions & metrics. It also provides time-based measurement tracking.
Similarly, Google Analytics has been proven to be a valuable addition to React SPA applications. Likewise, the same can be done with a Blazor application and the nuget package listed below. When used, GA will track events by default and can be explicitly invoked via code as needed.
- AppInsights – https://github.com/IvanJosipovic/BlazorApplicationInsights
- Google – https://github.com/isc30/blazor-analytics
Localization is not always a requirement for every application, but with .Net Core, there is usually some use of IStringLocalizer to perform translations. Blazor fully supports this client-side as well as during API calls. This allows for API routes to localize content response as needed by the user’s culture/language in the same way as a React SPA would. This also allows for client-side code translation if needed.
- Blazor globalization and localization – https://docs.microsoft.com/en-us/aspnet/core/blazor/globalization-localization?view=aspnetcore-5.0
Blazor is here! Blazor is ready! I am excited! Blazor is newer to the SPA landscape but checks a lot of the boxes needed to be chosen as part of the solution. There are areas (mostly due to the shorter time on the scene) where it lags React. However, there are key areas that, despite being relatively new where it surpasses React – models, validation, code-base-unity, to name a few. So IMHO, if your platform and/or background is .Net Core, Blazor is a YES for the next web application.