DEV Community

Cover image for Full Web Stack UI Development with Blazor and ComponentOne
Chelsea Devereaux for MESCIUS inc.

Posted on • Originally published at developer.mescius.com

Full Web Stack UI Development with Blazor and ComponentOne

What You Will Need

  • ComponentOne Blazor Edition
  • Visual Studio 2022

Controls Referenced

Tutorial Concept

How to create a Blazor web application using the latest .NET 8 Blazor Project template in Visual Studio 2022. This tutorial also uses ComponentOne FlexGrid and Input controls to build the interface.


Blazor, a modern web framework developed by Microsoft, has captured the attention of developers worldwide with its ability to seamlessly blend the flexibility of web development with the robustness of full-stack frameworks. 

In this comprehensive blog, we will delve into the advantages of Blazor for full-stack development, highlight the key updates introduced in ASP.NET Core 8.0 that further elevate the capabilities of Blazor, and walk through a tutorial using the latest Blazor Web Application Project template to create new applications in Visual Studio throughout the sections below:

Blazor Advantages for Full-Stack Development 

Blazor stands at the forefront of modern web development, offering developers a versatile framework for building interactive web applications using C# and .NET. Unlike traditional web development frameworks that rely heavily on JavaScript, Blazor empowers developers to leverage their expertise in C# for both client and server-side coding, eliminating the need to switch between multiple programming languages. At its core, Blazor combines the power of Razor syntax with the flexibility of .NET, providing developers with a familiar and efficient environment for building robust web applications. 

Blazor offers the following advantages for full-stack web development:

  1. Unified Development Environment: Blazor simplifies the development process by offering a unified environment for both client and server-side coding. Developers can write code once and deploy it across various hosting models, including Blazor Server and Blazor Web Assembly, without compromising performance or scalability.
  2. Component-Based Architecture: Blazor's component-based architecture promotes code reusability and modularity, allowing developers to create reusable UI components that can be easily integrated into various parts of the application. This approach enhances maintainability and scalability while reducing development time and effort.
  3. Rich Ecosystem: As an integral part of the .NET ecosystem, Blazor seamlessly integrates with existing .NET libraries and frameworks, providing developers access to a vast array of tools and resources. This rich ecosystem enhances productivity and enables developers to leverage their existing knowledge and skills.
  4. Performance: Blazor offers unparalleled performance by leveraging Web Assembly, a binary instruction format that enables near-native speed and performance in web browsers. This allows Blazor applications to run efficiently across all modern browsers, delivering a seamless and responsive user experience.
  5. Cross-Platform Ability: Blazor's cross-platform capabilities enable developers to build applications that can run on any modern browser, including mobile devices, without the need for additional plugins or add-ons. This ensures broad compatibility and accessibility for users across different platforms.
  6. Security: Blazor provides robust security features, including built-in support for anti-forgery protection and secure communication protocols. By keeping sensitive data and business logic on the server side, Blazor helps mitigate security risks and protect against malicious attacks.

ASP.NET Core 8.0 Updates for Blazor

The latest updates introduced in ASP.NET Core 8.0 further enhance the capabilities of Blazor applications. The following new features and improvements are offered for developers: 

  1. Blazor Web App Template: A new project template that combines the strengths of Blazor Server and Blazor Web Assembly with features like static SSR and enhanced navigation and form handling. 
  2. Enhanced Navigation and Form Handling: Blazor intercepts navigation and form submissions to perform fetch requests, improving page load times and user experience. 
  3. Anti-forgery Support: New anti-forgery features, including a component for rendering tokens and an attribute for enabling protection, enhance the security of Blazor forms. 
  4. Component Library Authorship: Guidance for library creators on authoring component libraries in Razor class libraries (RCLs) with static SSR. 

How to Setup a New Blazor Web Application 

In this section, we'll delve into utilizing the latest .NET 8.0 Blazor Web App template to create a single project that can be rendered on the server or through WebAssembly. Within our sample application, we'll be crafting two essential pages (also called components in Blazor): 

1.Register Page: This component page serves as a user registration form for employees, enabling users to input crucial details such as social security number, name, date of joining, department, and address. Through this, we'll explore the intricacies of Form Handling and delve into the Model Binding features of .NET 8 using our custom controls.

Blazor Register Page

2.Records Page: Here, we'll showcase a Flexgrid that elegantly presents employee details in a tabular format. Additionally, whenever a new employee is registered, their information seamlessly integrates into the grid, ensuring a cohesive user experience.

Blazor Records Page

Prerequisites: 

  1. To access .NET 8.0, visit Microsoft's official website
  2. For .NET 8, ensure you have Visual Studio 2022 version 17.8 or later installed. You can also acquire the most recent version of Visual Studio.

Create an Empty Blazor Web App

  1. Launch Visual Studio and create a new project from the menu or the “Get Started” page.
  2. In the “Create a new project” dialog, opt for the “Blazor Web App” template and proceed by clicking “Next.” This is the latest project template that combines Blazor Server and WebAssembly rendering modes.

Blazor Create New Project

3.Provide a name for your project, set up the project location, and then proceed by clicking “Next.” 

Blazor Configure Project

4.On the “Additional information” page, you can leave the default options selected. By default, the Framework is “.NET 8.0,” the Authentication type is “None,” the Interactive render mode is “Server,” and the Interactivity location is “Per page/component.” 

Blazor Additional Info

Your new Blazor web app has been created!

Create the Employee Class  

Next, we need to set up the data model for our application.

  1. In the root directory of your project, create a folder named "Data."
  2. Inside the "Data" folder, add a file called "Employee.cs." 
  3. Add the following directive:
    using System.ComponentModel.DataAnnotations;  
Enter fullscreen mode Exit fullscreen mode

4.Within the "Employee.cs" file, define the Employee classes.

The Employee class represents individual employee details such as Social Security Number, Name, Address, Date of Joining, and Department. It also includes methods to generate random employee details and manage the collection of employees.

    public class Employee {  
        private static List<Employee> employees = new List<Employee> (); // Collection to store employee details  
        public string Id { get; set; }  

        [Required(ErrorMessage = "Social Security Number is required")]  
        public string SocialSecurityNumber { get; set; }  

        [Required(ErrorMessage = "Name is required")]  
        public string Name {get; set; }  

        public string Address { get; set; }  

        [Required(ErrorMessage = "Date of Joining is required")]  
        public DateTime DOJ { get; set; }  

        public string Department { get; set; }  

        // Get All the Employees   
        public static List<Employee> GetAllEmployees()  
        {  
            return employees;  
        }  

        // Add An Employee to the Begining Of the List  
        public static void AddEmployee(Employee employee)  
        {  
            employees.Insert(0, employee);  
        }  
    }  

Enter fullscreen mode Exit fullscreen mode

Add the ComponentOne Dependencies

For this Blazor tutorial, we need to install some additional libraries to complete the UI. We’ll be using several components from the ComponentOne Blazor Edition. All of these components can be installed from NuGet.org, and if you’re installing them for the first time, they will initiate a 30-day trial.

To install these dependencies for your project, follow the steps below: 

  1. Navigate to the Project menu and select "Manage NuGet Packages." 
  2. In the NuGet Package Manager window, ensure that "NuGet.org" is selected as the Package source. 
  3. Search for the following packages: C1.Blazor.Grid, C1.Blazor.Calendar, C1.Blazor.Core, and C1.Blazor.Input. 
  4. Select these packages and click on the "Install" button to proceed with the installation of the dependencies. Navigate to the Components folder and open the "App.razor" page.
  5. Within the section of the "App.razor" page, add the following CSS (Cascading Style Sheets) references:
            <link rel="stylesheet" href="/_content/C1.Blazor.Core/styles.css" /> 
            <link rel="stylesheet" href="/_content/C1.Blazor.Grid/styles.css" /> 
            <link rel="stylesheet" href="/_content/C1.Blazor.ListView/styles.css" /> 
            <link rel="stylesheet" href="/_content/C1.Blazor.Input/styles.css" /> 
            <link rel="stylesheet" href="/_content/C1.Blazor.Menu/styles.css" /> 
            <link rel="stylesheet" href="/_content/C1.Blazor.DataFilter/styles.css" /> 
            <link rel="stylesheet" href="/_content/C1.Blazor.Calendar/styles.css" /> 
            <link rel="stylesheet" href="/_content/C1.Blazor.DateTimeEditors/styles.css" /> 
Enter fullscreen mode Exit fullscreen mode

6.In the section of the same page, add the following JavaScript references:

            <script src="/_content/C1.Blazor.Core/scripts.js"></script> 
            <script src="/_content/C1.Blazor.Input/scripts.js"></script> 
            <script src="/_content/C1.Blazor.Grid/scripts.js"></script> 
            <script src="/_content/C1.Blazor.Menu/scripts.js"></script> 
            <script src="/_content/C1.Blazor.Calendar/scripts.js"></script> 
             <script src="_framework/blazor.web.js"></script> 
Enter fullscreen mode Exit fullscreen mode

7.In the “_Imports.razor” page, import the C1modules so that they can be used across various components.

        @using C1.Blazor.Grid 
        @using C1.Blazor.Input 
        @using C1.Blazor.Core 
        @using C1.DataCollection 
        @using C1.Blazor.Input 
        @using C1.Blazor.Core 
        @using C1.Blazor.Calendar 
        @using C1.Blazor.DateTimeEditors
Enter fullscreen mode Exit fullscreen mode

With these references added, your Blazor application will be equipped with the necessary CSS and JavaScript files to support the functionality provided by the C1.Blazor components.

Create the Employee Register Page

Go to the Components folder, then the Pages folder, and create a new "Register.razor" page. 

This Blazor component page will serve as a registration form for employees. It will allow users to input their social security number, name, date of joining, department, and address. 

Let's proceed with completing the Register Page as indicated below: 

1.Setting Up the Register Page

        @page "/register" 
        @rendermode InteractiveServer 
        @using Data 
        @inject NavigationManager Navigation 
Enter fullscreen mode Exit fullscreen mode

The @rendermode directive sets the rendering mode of our component to "InteractiveServer." This mode ensures that UI updates are processed on the server side and sent to the client over a SignalR connection, enabling dynamic and responsive behavior without requiring full page reloads. 

The NavigationManager Service is injected in the component.

2.Building the User Interface

        <EditForm Model="employee" @ref="editFormRef"> 
            <DataAnnotationsValidator /> 
            <div class="form-group"> 
                <label for="name">Social Security Number:</label> 
                <C1MaskedTextBox MaskFormat="000-00-000" 
                                 DisplayMode="MaskDisplayMode.Always" 
                                 Mask="000-00-0000" 
                                 Placeholder="Social Security Number" 
                                 @bind-Text="employee.SocialSecurityNumber" 
                                 Class="form-control"> 
                </C1MaskedTextBox> 
                <ValidationMessage For="@(() => employee.SocialSecurityNumber)" /> 
            </div> 

            <div class="form-group"> 
                <label for="department">Department:</label> 
                <C1ComboBox ItemsSource="departments" T="string" 
                            Placeholder="Select Department" 
                            @ref="DepartmentComboBox" 
                            SelectedIndex="0" 
                            class="form-control" /> 
                <ValidationMessage For="@(() => employee.Department)" /> 
            </div> 

            <button type="submit" class="btn-submit" @onclick="RegisterEmployee"> 
                Register 
            </button> 
        </EditForm> 
Enter fullscreen mode Exit fullscreen mode

The Model parameter binds the form fields to the properties of the employee object, facilitating data synchronization between the UI and the underlying model. Additionally, the @ref parameter allows us to obtain a reference to the form for further interaction within our component.

The form includes various UI components from the ComponentOne Blazor Edition library for enhanced functionality, such as masked text input for the social security number and date picker for selecting the date of joining. Data binding is employed to synchronize form inputs with properties of the employee model object. The component page also features form validation using data annotations, ensuring that user inputs meet specified criteria.

3.Register the Employee

            private async Task RegisterEmployee() 
            { 
                // Validate the Form 
                var isValid = editFormRef.EditContext.Validate(); 
                if (isValid) 
                { 
                    Employee newEmployee = new Employee 
                        { 
                            SocialSecurityNumber = employee.SocialSecurityNumber, 
                            Name = employee.Name, 
                            Address = employee.Address, 
                            DOJ = employee.DOJ, 
                            Department = (string)DepartmentComboBox.SelectedValue 
                        }; 
                    // Add the new employee to the list of employees 
                    Employee.AddEmployee(newEmployee); 
                    // Navigate to "Records" Component 
                    Navigation.NavigateTo("/"); 
                } 
                StateHasChanged(); 
            } 
Enter fullscreen mode Exit fullscreen mode

This code validates the form. Upon successful registration, the employee details are stored, and the user is navigated to the Records Page (component).

Create the Records Page 

Go to the Components folder, then the Pages folder, and then create another page named "Records.razor." 

This Blazor component page, titled "Records," will display a list of employee records in a grid format. It allows users to search for specific records, optionally group records by department, and view various details such as name, social security number, date of joining, and full address. It also integrates functionalities like data binding, filtering, grouping, and asynchronous data loading to provide a comprehensive view of employee data. 

Let's proceed with creating the "Records" page as indicated below:

1.Setting Up the Component Page

        @page "/" 
        @rendermode InteractiveServer 

Enter fullscreen mode Exit fullscreen mode

The @rendermode directive sets the rendering mode of our component to "InteractiveServer."

2.Building the User Interface

        <div class="records-component"> 
            <C1TextBox @bind-Text="filterString" Placeholder="Search" Style="@("margin:8px 0")" /> 
            <span style="color:#d32f2f;font-size:18pt">Group By Department</span> 
            <C1CheckBox IsChecked="grouped" IsCheckedChanged="OnGroupByDepartmentChanged" Style="@("margin-left:8px")" /> 
            <FlexGrid ItemsSource="employeeDataCollection" @ref="grid" 
                      IsReadOnly="true" 
                      HeadersVisibility="GridHeadersVisibility.Column" 
                      AlternatingRowStyle="@("background-color:#F5F5F5")" 
                      Style="@("max-height: 65vh")" 
                      AutoGenerateColumns="false"> 
                <FlexGridColumns> 
                    <GridColumn Binding="Name" MinWidth="40" Width="GridLength.Star" 
                                HorizontalAlignment="C1HorizontalAlignment.Left" HeaderHorizontalAlignment="C1HorizontalAlignment.Left" /> 
                    <GridColumn Binding="Department" MinWidth="50" Width="GridLength.Star" 
                                HorizontalAlignment="C1HorizontalAlignment.Left" HeaderHorizontalAlignment="C1HorizontalAlignment.Left" /> 
                    <GridColumn Binding="SocialSecurityNumber" MinWidth="110" MaxWidth="130" Width="GridLength.Star" 
                                HorizontalAlignment="C1HorizontalAlignment.Left" HeaderHorizontalAlignment="C1HorizontalAlignment.Left" /> 
                    <GridDateTimeColumn Binding="DOJ" Header="Date Of Joining" Format="d" 
                                        Mode="GridDateTimeColumnMode.Date" MinWidth="70" Width="GridLength.Star" 
                                        MaxWidth="70" 
                                        HorizontalAlignment="C1HorizontalAlignment.Left" HeaderHorizontalAlignment="C1HorizontalAlignment.Left" /> 
                    <GridDateTimeColumn Binding="Address" AllowFiltering="false" 
                                        MaxWidth="130" 
                                        Header="Full Address" MinWidth="300" 
                                        Width="GridLength.Star" HorizontalAlignment="C1HorizontalAlignment.Left" HeaderHorizontalAlignment="C1HorizontalAlignment.Left" /> 
                </FlexGridColumns> 

                <FlexGridBehaviors> 
                    <FullTextFilterBehavior FilterString="@filterString" HighlightStyle="@("color:#3E65FF")" TreatSpacesAsAndOperator="true" /> 
                </FlexGridBehaviors> 
            </FlexGrid> 
        </div> 
Enter fullscreen mode Exit fullscreen mode

Add a FlexGrid to the component page. The C1TextBox will act as an input for the filter string, and the C1CheckBox will group the data by department.

3.Loading the Data

          protected override async Task OnInitializedAsync() 
            { 
                employees = Employee.GetAllEmployees(); 
                employeeDataCollection = new C1DataCollection<Employee>(employees); 
            } 
Enter fullscreen mode Exit fullscreen mode

This fetches all the "Employees" data and adds the employeeDataCollection as an item source to the datagrid.

Build and Run the Project

Alternatively, if you haven’t followed the above steps, you can download the completed sample

To compile and launch the project, follow the steps below: 

  1. Select Build > Build Solution to compile the project. 
  2. Press the F5 key to initiate the project execution.

Blazor Records Page Final

We’ve omitted a few things, like additional navigation and CSS styling enhancements, which you’ll see in the attached sample. To incorporate navigation links for accessing components, refer to the updated "NavMenu.razor" page in the sample. For styling enhancements, refer to the updated "app.css" file in the sample.

Conclusion

In today's rapidly evolving technological landscape, where innovation drives progress, Blazor has emerged as a revolutionary force in web development. Its C# component-based architecture enhances code reusability and user experiences. Though Blazor relies on primitive HTML-driven UIs, this can be rapidly accelerated through rich component libraries such as ComponentOne Blazor Edition. Plus, ASP.NET Core 8.0's upgrades streamline development and bolster performance, empowering developers to create responsive, scalable applications with .NET's security and reliability.

Top comments (0)