Yes, Syncfusion Blazor components are indeed mobile-friendly. They have been developed with a mobile-first approach, ensuring that they are responsive and adaptive across various devices. This means that whether users access applications built with Syncfusion Blazor components on desktops, tablets, or smartphones, they will experience consistent usability and functionality.
Comprehensive Component Library: The Syncfusion Blazor UI library includes unique components: Diagram, Smith Chart, Bullet Chart, Kanban Chart, Rating, Word Processor, Image Editor, Mention, AppBar, Speed Dial, Message, Toast, In-place Editor, Query Builder, and PowerPoint library.
Theming and Customization: Customize your Blazor application with our Fluent, Material 3, Bootstrap 5, high contrast, or dark mode themes. Additionally, our Theme Studio tool allows rich customization of these themes according to your preferences.
Performance Optimization: Syncfusion provides a CRG (custom resource group) to optimize loading performance by selectively loading specific component scripts and CSS styles as needed.
Adaptive and Touch-Friendly Design: All Syncfusion Blazor components are touch-friendly and adaptively render based on device, ensuring an optimal user experience across phones, tablets, and desktops.
Data and UI Virtualization: For large-scale applications, applicable components support data and UI virtualization, enhancing performance and scalability. This feature is available in components like DataGrid, Scheduler, and Gantt Chart.
Seamless Data Binding: Syncfusion Blazor components support seamless data binding for data-bound controls such as DataGrid, Pivot Table, Gantt Chart, and Scheduler. It includes two-way data binding for applicable component properties, enabling efficient data management.
Extensive Documentation and Demos: Access over 1,000 interactive demos, comprehensive user guide documentation, and class references to facilitate a smoother learning curve and implementation process.
Instead of using the DataAnnotationValidator in Blazor, you can use FluentValidation to implement form validation. FluentValidation is a common validation library for.NET Core that offers a few advantages over the built-in DataAnnotations validation library, such as a larger set of rules, simpler setup, and extensibility.
Install the “FluentValidation” package using the NuGet package manager.
Create a new folder named FluentValidation in the main application and add the following *.cs files – Employee, EmployeeValidator, FluentValidationValidator to it as shown below.
Add a model Employee class name in the Employee.cs file.
namespace {AppName}.FluentValidation { public class Employee { public string Name { get; set; } public string Organization { get; set; } } }
To write a model validator, you must create a EmployeeValidator class that is inherited from the AbstractValidator<Employee> and then add all the validation rules for the respective model to the constructor.
using FluentValidation;
namespace {AppName}.FluentValidation { public class EmployeeValidator : AbstractValidator<Employee> { public EmployeeValidator() { RuleFor(p => p.Name).NotEmpty().WithMessage("You must enter a valid name."); RuleFor(p => p.Name).MaximumLength(20).WithMessage("The name cannot be more than 20 characters long."); RuleFor(p => p.Organization).NotEmpty().WithMessage("You must enter a valid organization name."); } } }
In FluentValidationValidator.cs, create a new validator component named FluentValidationValidator to replace DataAnnonationsValidator, and add the code below to it.
The FluentValidationValidator receives an EditContext as a cascading parameter and hooks into the EditContext’sOnFieldChanged and OnValidationRequested events to know when something is happening in the UI. It can add or remove validation messages from a ValidationMessageStore at any time.
using System; using FluentValidation; using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components.Forms;
namespace {AppName}.FluentValidation { public class FluentValidationValidator<TValidator> : ComponentBase where TValidator : IValidator, new() { private readonly static char[] separators = new[] { '.', '[' }; private TValidator validator;
protected override void OnInitialized() { validator = new TValidator(); var messages = new ValidationMessageStore(EditContext);
/* Re-validate when any field changes or when the entire form requests validation.*/ EditContext.OnFieldChanged += (sender, eventArgs) => ValidateModel((EditContext)sender, messages);
while (true) { var nextTokenEnd = propertyPath.IndexOfAny(separators); if (nextTokenEnd < 0) { return new FieldIdentifier(obj, propertyPath); }
var nextToken = propertyPath.Substring(0, nextTokenEnd); propertyPath = propertyPath.Substring(nextTokenEnd + 1);
object newObj; if (nextToken.EndsWith("]")) { nextToken = nextToken.Substring(0, nextToken.Length - 1); var prop = obj.GetType().GetProperty("Item"); var indexerType = prop.GetIndexParameters()[0].ParameterType; var indexerValue = Convert.ChangeType(nextToken, indexerType); newObj = prop.GetValue(obj, new object[] { indexerValue }); } else { var prop = obj.GetType().GetProperty(nextToken); if (prop == null) { throw new InvalidOperationException($"Could not find property named {nextToken} in object of type {obj.GetType().FullName}."); } newObj = prop.GetValue(obj); }
if (newObj == null) { return new FieldIdentifier(obj, nextToken); }
obj = newObj; } } } }
Add the following code to the Index.razor page to perform fluent validation using the FluentValidationValidator component and its model validator (EmployeeValidator) in the EditForm component.
The DisplayName property, which is set for
built-in form components, help maintain an alternate name. When the component’s
input value is incorrect due to form validation, this alternate name is
displayed in the error message.
The DisplayName property is supported
by the following built-in components.
By default, the System.ComponentModel.Annotations library provides different validation attributes. However, to add a new or custom validation, users can create a custom validation attribute and apply it to their model class. To create an attribute:
Install the System.ComponentModel.Annotations NuGet package to perform custom validation in Created project.
Create a new folder named Models in the main application and add the following *.cs files –EmployeeDetails, OrganizationValidationAttribute to it as shown below.
Add a model EmployeeDetails class name in the EmployeeDetails.csfile.
using System.ComponentModel.DataAnnotations; namespace BlazorServerApp.Models { public class EmployeeDetails { [Required] public string? Name { get; set; } [Required] public string? Organization { get; set; } } }
Create a new OrganizationValidationAttribute.cs file and then the OrganizationValidationAttribute class, which is derived from ValidationAttribute. The ValidationAttribute from System.ComponentModel.Annotations acts as the base class for validation.
[OrganizationValidationAttribute.cs]
using System.ComponentModel.DataAnnotations; namespace BlazorServerApp.Models { public class OrganizationValidationAttribute : ValidationAttribute { public string? ValidOrganizationName { get; set; } protected override ValidationResult? IsValid ( object? value, ValidationContext? validationContext ) { string fieldValue = value!.ToString()!.ToLower(); if (fieldValue.Equals(ValidOrganizationName?.ToLower())) return null; return new ValidationResult(ErrorMessage, new[] { validationContext?.MemberName }.Cast()); } } }
The ValidOrganizationName property can be set from the model EmployeeDetails class. Following that, override the IsValid method, which takes two parameters, value and validationContext. The value parameter contains the value that the user entered in the Organization field. The validationContext parameter is used to explain the context in which validation is performed. If the value is equal to the ValidOrganizationName, no errors will be thrown; otherwise, an error message returns.
Add the following custom validation attribute to the Organization property.
using System.ComponentModel.DataAnnotations; namespace BlazorServerApp.Models { public class EmployeeDetails { [Required] public string? Name { get; set; } //Here OrganizationValidation is a Customvalidation Attribute [Required] [OrganizationValidation(ErrorMessage = "Invalid customer log-in.", ValidOrganizationName = "Syncfusion")] public string? Organization { get; set; } } }
Moving back to the Blazor Server application, add the following code to the Index.razor page to render a form with validation settings.
The built-in DataAnnotationsValidator allows you to validate form input using data annotations, but it only validates top-level properties bound to the form and not child or complex type properties. To validate the nested complex model, replace the DataAnnotationsValidator with the ObjectGraphDataAnnotationsValidator, which validates the entire object, including child and complex type properties in the form.
Install the following package via Package Manager Console in order to use the ObjectGraphDataAnnotationsValidator.
Create a new Folder named StudentDetails in the main application and add the class named Student.cs to the StudentDetails folder. In Student.cs file, create two model classes -Student and PersonalDetails. Here, add ValidateComplexType belonging to the ObjectGraphDataAnnotationsValidator above the complex type declaration.
using System.ComponentModel.DataAnnotations; namespace Validating_Complex_Model_in_Blazor.StudentDetails { public class Student { public Student () { Details = new PersonalDetails(); }
[Required] public string Name { get; set; } [Required] public string Department { get; set; } [ValidateComplexType] public PersonalDetails Details { get; set; } }
public class PersonalDetails { [Required] public int Age { get; set; }
[Required] public string? Address { get; set; } } }
Create an Index.razor page with the EditForm and Input components shown in the code sample below. Set the Model property of the EditForm component to the Student class instance. Additionally, the ObjectGraphDataAnnotationsValidator and ValidationSummary tags are used for validation and the display of validation summary, respectively.
The EditContext of the form stores information about the editing process, such as which fields have been changed and which validation messages are currently displayed. To manually pass the EditContext to the EditForm, follow the steps below.
Create a new Customer.cs file and model Customer class.
public class Customer { [Required] public string Name { get; set; }
[Required] [StringLength(4, ErrorMessage = "The organization code must be less than 5 characters in length.")] public string OrganizationCode { get; set; } }
Insert an EditForm component into the Index.razor page. Then, make instances of the Customer class and the EditContext, and assign the Customer class instance to the EditContext instance. Finally, bind the EditContext instance to the EditContext property in the EditForm component.
As the EditContext stores all the form information, it can be used to validate the form components. Add the Razor code as given below with input texts and a button. When a form is submitted, the Validate() method is invoked to perform validation.
To add custom CSS class names to input components despite bootstrap and other CSS framework styling, follow the steps below.
In the wwroot/css/site.css stylesheet, include the following styles.
.validField { outline: 2px dotted green; }
.invalidField { outline: 2px dotted red; }
Create a new Customer.cs and model Customer class.
using System.ComponentModel.DataAnnotations;
namespace CustomCSS_Validation_InputComponent { public class Customer { [Required] public string Name { get; set; }
[Required] [StringLength(4, ErrorMessage = "The organization code must be less than 5 characters in length.")] public string OrganizationCode { get; set; } } }
Create a new CustomFieldCssClassProvider.cs and then the CustomFieldCssClassProvider class.Inherit the CustomFieldCssClassProvider class from FieldCssClassProvider and override the GetFieldCssClass method, which helps to check for validation messages with the EditContext and returns the “validField” or “invalidField” class name to the appropriate field.
using Microsoft.AspNetCore.Components.Forms; using System.Linq;
namespace FormBootstrapCSS.Data { public class CustomFieldCssClassProvider : FieldCssClassProvider { public override string GetFieldCssClass(EditContext editContext, in FieldIdentifier fieldIdentifier) { var isValid = !editContext.GetValidationMessages(fieldIdentifier).Any();
Add the form design code as well as the code for input components validation to the Index.razor page. Here, the SetFieldCssClassProvider method in the EditContext class is used to set the custom CSS name to the appropriate field based on the validation result returned by the CustomFieldCssClassProvider class, whose instance is passed into the method.
To use .npm packages in a Blazor WebAssembly application, follow these steps:
Create a Blazor WebAssembly application in Visual Studio 2019 using this link.
Right-click on the application and create a new folder named npm_packages.
Open the npm_packages folder directory via command prompt and run the following command to initialize NPM in the application.
npm init -y
Once the command is executed, it will create a new package.json file in the npm_packages directory.
Continue in the command prompt by executing the following command to install a JavaScript bundler named webpack and its CLI as development dependencies.
npm install webpack webpack-cli –save-dev
Finally, install the required .npm package. In this demo, we installed Syncfusion Maps by running the following command.
npm install @syncfusion/ej2-maps
Within the npm_packages folder, create a new folder called src, and then a JavaScript file called index.js.
Include the build script for the package.json file, as shown in the following, which uses webpack to bundle the JavaScript file. This script tells webpack to use the index.js file in the src folder as the source file. The output directory of the bundled file is then set to be created under the js folder in the wwwroot folder directory as index.bundle.js.
Navigate to the Index.razor page and insert a div tag with the id set as element to display the Syncfusion Maps component. [Index.razor]
@page "/"
<h1>NPM Packages Demo</h1>
<div id="element"></div>
In the index.js file, import and declare the Syncfusion Maps component. Finally, the component is appended to the div tag with the id set as element in the Index.razor page. [index.js]
Modify the index.html file with the following code to help Blazor inject a script after it starts. Note: This step is primarily for including the Syncfusion Maps component; if you’re using something else, you can skip it.
CORS stands for cross-origin resource sharing, and it is an HTTP header-based mechanism that allows the server to tell the browser whether to accept a request from a domain, port, or scheme other than its own. It is based on a process in which the browser sends a “preflight” request to the server, and the server responds with response headers indicating whether the request can proceed or not. The browser will either succeed or fail the request based on what these headers say. The browser sends headers that indicate the HTTP method and headers that will be used in the actual request in the preflight request.
To enable CORS in your Blazor Server application, follow these steps:
After creating the application, open the Program.cs file. In this file, you will find the code where the AddCors method is called on the builder.Services object to register the CORS service. Within the AddCors method, a named CORS policy called “NewPolicy” is defined using the options.AddPolicy method. If necessary, you can further configure the CORS policy by providing additional options through the builder parameter in the AddPolicy method. [Program.cs]
Bundling is the process of combining multiple files into a single file. Minifying is the process of removing unnecessary data such as comments and extra spaces, as well as converting a large variable name into a smaller name without affecting its functionalities.
To bundle and minify the CSS and JS files in a Blazor application, follow these steps:
Install the BuildBundlerMinifier NuGet package and reference it in the .csproj file, as shown.
After you build your application, the bundled and minified files are generated as shown in the following image. You can reference these files in your application based on the requirement.
The AddDefaultPolicy method allows you to add a new policy to the CORS configuration and make it the application’s default. In the Program.cs file, you can call the AddCors method to add the cross-origin resource sharing services to the service collection. To add a default policy to the configuration, you can call the AddDefaultPolicy within the AddCors method. Since you are using the default policy, there is no need to include the policy name in the UseCors method, as shown.
The AddPolicy method allows you to add a custom policy to the CORS configuration and give it a name for identification. In the Program.cs file, to add a user-defined (custom) policy to the configuration, you can call AddPolicy within the AddCors method.
SEO is an abbreviation for search-engine optimization,
and it refers to the process of optimizing a website for search engines. In
simpler words, it refers to the process of improving your website in order to
increase its visibility when people use Google, Bing, and other search engines
to find what they’re looking for.
The best way to make your Blazor WebAssembly application SEO-friendly is to work on the title, meta description, and H1 tag in the index.html common page or in individual pages based on your requirements and development activities. If you include keywords in the title, meta description, and H1 tag of your Blazor WebAssembly application, the app will appear near the top of search engine results when people search for general information using those keywords.
Title: The title must be text-only and appears in the browser’s title bar or in the page’s tab.
H1 tag: The H1 tag will be displayed as the application’s top-level heading.
Meta description: The meta description will be displayed as compressed content just below the search-related link.
Meta keywords: If anyone searches for a keyword mentioned in your Blazor application, it will appear at the top of the search engine results. However, Googlebot no longer considers meta keywords to be SEO-friendly.
Note: Make sure that your
title, H1 tag, and meta description are unique. If the description or title is
too long, Google will limit the content to a specific range. Follow these guidelines to avoid unwanted
content loss:
Title: should be
between 20 and 70 characters long.
Meta description:
should be between 100 and 160 characters long.
SEO is an abbreviation for search-engine optimization,
and it refers to the process of optimizing a website for search engines. In
simpler words, it refers to the process of improving your website in order to
increase its visibility when people use Google, Bing, and other search engines
to find what they’re looking for.
The best way to make your Blazor Server application SEO-friendly is to work on the title, meta description, and H1 tag in the _Host.cshtml common page or in individual pages based on your requirements and development activities. If you include keywords in the title, meta description, and H1 tag of your Blazor Server application, the app will appear near the top of search engine results when people search for general information using those keywords.
Title: The title must be text-only and appears in the browser’s title bar or in the page’s tab.
H1 tag: The H1 tag will be displayed as the application’s top-level heading.
Meta description: The meta description will be displayed as compressed content just below the search-related link.
Meta keywords: If anyone searches for a keyword mentioned in your Blazor application, the app will appear at the top of the search engine results. However, Googlebot no longer considers meta keywords to be SEO-friendly.
Note: Make sure that your
title, H1 tag, and meta description are unique. If the description or title is
too long, Google will limit the content to a specific range. Follow these guidelines to avoid unwanted
content loss:
Title: should be
between 20 and 70 characters long.
Meta description:
should be between 100 and 160 characters long.
In a Blazor application, you can call JavaScript functions from C# (.NET) methods and vice versa. This is referred to as “JavaScript interoperability” or “JS interop.” The JS interop allows you to integrate JavaScript libraries into your Blazor application, and its primary function is to handle DOM manipulation and browser API calls.
Please refer to this link to
learn more about JS interop in Blazor.
Please refer to this link for
calling and implementing JS interop in Blazor.
You can change
the CSS value in the Blazor application by using the following options.
Internal CSS
Inline CSS
Declare and assign a variable to the
respective DOM element.
NOTE: In CSS, the “!important” rule is used to give a property more weightage, that is, it will override all the previous styling rules applied to that element for that specific property.
[Index.razor]
@page "/"
<style>
.divStyle {
font-family: 'Courier New';
color: red !important;
}
</style>
<div class="divStyle"> This is internal CSS styling. </div>
<div style="font-family: 'Times New Roman'; color: green !important;"> This is inline CSS styling. </div>
<div style="@styleInfo"> This CSS styling is applied by declaring a variable. </div>
@code {
public string styleInfo = "font-family: 'Calibri'; color: blue !important;";
}
Stored procedures are pieces of reusable code that you can save in a database data dictionary. They help you extract, edit, and remove data from a database without writing the code to do so again and again. It also saves your time, lessens your workload, and increases your productivity. Follow these steps to use stored procedures in a Blazor application:
Create a class named EmpClass.cs in the Data folder and define the properties that are already in the database table. [Empclass.cs]
public class EmpClass { [Key] public int Empid { get; set; } public string? Empname { get; set; } public string? Department { get; set; } public DateTime joinDate { get; set;} }
[EmpClass table] Also Define inserted Employee Details in stored procedure.
CREATE PROCEDURE [dbo].[InsertEmpdetails] @Empname nvarchar(150), @Department nvarchar(150), @joinDate datetime AS Insert into EmpClass(Empname,Department,joinDate) values (@Empname,@Department,@Joindate) RETURN 0
Add the virtual property for the DbSet from EmpClass to insert records in the database under the Data folder. [ApplicationDbContext.cs]
public class ApplicationDbContext:DbContext { public ApplicationDbContext(DbContextOptions options ) : base(options) { } public virtual DbSet InsertRecord { get; set; } }
Connect the SQL Server database to the Blazor application by choosing (View –> Server Explorer). Right-click the Data Connections and choose Add connection in Visual Studio. Add your server name and DB name to connect the database to the Blazor application. The database is now connected to the Blazor application.
Add the connection string configurations to the appsetting.json file. [appsetting.json]
The Dispose method is used to avoid memory leaks and allows proper garbage collection. Implement the IDisposable interface in the component and call the Dispose method. If the framework calls the Dispose method, the component is removed from the UI and unmanaged resources can be released.
The following example demonstrates the disposal of Timer in the counter page.
A progressive web application (PWA) is usually a single-page application (SPA) used to create a Blazor WebAssembly application to work offline. It runs in its own app window and independent of network speed.
Follow these steps to create a Blazor WebAssembly PWA application to work offline.
Create a Blazor WebAssembly application with a progressive web application configuration.
Press Ctrl + F5 to run the application. Users have the option of installing the app.
Once the app is installed, the app appears in its own window without an address bar.
To achieve two-way binding with the Select component in Blazor, you can use the @bind directive. Here’s an example of how you can implement two-way binding with the Select component:
Using the StateHasChanged() method, you can force a re-render of your Blazor component. The StateHasChanged() method notifies that the state has been changed and requires a re-render of the component.
To apply custom CSS style to a Blazor component, create a custom CSS file in your Razor page with the name of razorpage.css (i.e. Index.razor.css) and add your styles.
Now, create a new custom validation class in the Pages folder and restrict the user to enter only “admin” in the password field. [CustomValidatorAttribute.cs]
using System.ComponentModel.DataAnnotations;
namespace {{Your_App_Name}}.Pages { public class CustomValidationAttribute : ValidationAttribute { public string? ValidUserName { get; set; } protected override ValidationResult? IsValid ( object? username, ValidationContext validationContext ) { var content = username?.ToString()?.ToLower(); if (content!.Equals(ValidUserName?.ToLower())) { return null; } return new ValidationResult(ErrorMessage, new[] { validationContext.MemberName }); } } }
Use the created custom validator attribute in the Razor component. Provide the error message and valid username properties for validation. [Index.razor]
Using C# conditional preprocessor directives and predefined constants, you can check the Blazor target framework version. For example, if the framework targets .NET 6.0, or latest version the code is compiled only in that specified condition. Follow these steps to check the Blazor target framework version.
[Index.razor]
@page "/"
<h1>@blazorVersion</h1>
@code {
private string? blazorVersion { get; set; }
protected override void OnInitialized ()
{
#if NET6_0
blazorVersion = "Blazor App version is .NET6.0";
#elif NET5_0
blazorVersion = "Blazor App version is .NET5.0";
#elif NETCOREAPP3_1
blazorVersion = "Blazor App version is netcoreapp3.1";
#endif
}
}
By calling the StateHasChanged() method in Blazor, you can receive notifications about state changes and trigger component re-rendering to push the changes to the browser using SignalR. An example that illustrates this functionality is the Counter component. In this example, the component automatically pushes incremented count data using the Timer function and updates the UI in the browser by invoking the StateHasChanged() method within the InvokeAsync action.
[Counter.razor]
@page "/counter"
@using System.Timers
<h1>Counter</h1>
<p>Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@code {
private int currentCount = 0;
private Timer time;
private void IncrementCount()
{
currentCount++;
}
protected override void OnAfterRender(bool firstRender)
{
if (firstRender)
{
time = new Timer();
//Set the time interval.
time.Interval = 1000;
time.Elapsed += OnTimeInterval;
time.AutoReset = true;
// Start the timer.
time.Enabled = true;
}
base.OnAfterRender(firstRender);
}
Private async void OnTimeInterval(object sender, ElapsedEventArgs e)
{
IncrementCount();
await InvokeAsync(() => StateHasChanged());
}
public void Dispose()
{
// While navigating to other components, Dispose method will be called and clean up the Timer function.
time?.Dispose();
}
}
Use HttpContext through the IHttpContextAccessor interface to get the user agent details in a Blazor Server application. The following example demonstrates how to use HttpContext to get the user agent and IP address details by default. Extend the AddHttpContextAccessor() method in the Program.cs file.
In a Blazor Server app, the default RenderMode is Server Prerendered. When the component is rendering with the ServerPrerendered render mode, the component is initially rendering statically as part of the page.
On executing the first time, it is rendered as an MVC component directly when the page is requested and handled by “_Host” which is specified in “_Host.cshtml”.
Then the resources are loaded with the blazor.server.js script and start rendering a second time. Then the Razor pages are loaded as a Blazor component. Note: If you are changing the RenderMode to Server, the lifecycle method executes only once.
Use the System.Timers.Timer class to wait until the user has finished typing in the text field. The onkeyup event triggers for each key press and resets the timer until the last timer raises the OnUserFinish event.
By utilizing browser storage in Blazor, you can effectively save and load data within a component. In the following example, you can see how the counter value is updated with a button click and the count value is stored in the local storage of the browser. When you refresh the page, the saved data will be loaded from the browser’s local storage.
[Index.razor]
@page "/"
@using Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage
@inject ProtectedLocalStorage LocalStorage
@if (isCount)
{
<p>Current count: <strong>@currentCount</strong></p>
<button class="btn btn-primary" @onclick="IncrementCount">Increment</button>
}
else
{
<p>Loading...</p>
}
@code {
private int currentCount;
private bool isCount;
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
isCount = true;
// Get the count value into browser local storage.
var countValue = await LocalStorage.GetAsync<int>("countValue");
// Loaded the browser local storage value to currentCount.
currentCount = countValue.Success ? countValue.Value : 0;
StateHasChanged();
}
}
private async Task IncrementCount()
{
currentCount++;
// Set the count value in browser local storage.
await LocalStorage.SetAsync("countValue", currentCount);
}
}
IndexedDB is used for the client-side storage of data and files. Follow these steps to use IndexedDB in Blazor WebAssembly:
Create a Blazor WebAssembly app and install the IndexedDB.Blazor NuGet package using the NuGet package manager.
Set up the IIndexedDbFactory configuration service in your Program.cs file and set it as scoped.[Program.cs]
using IndexedDB.Blazor; builder.Services.AddScoped();
Now add the properties inside the class to store and process data in the Data folder. [IndexDb.cs]
using IndexedDB.Blazor; using Microsoft.JSInterop; using System.ComponentModel.DataAnnotations; namespace Blazor_WebAssembly_App.Data { public class IndexDb : IndexedDb { public IndexDb ( IJSRuntime jSRuntime, string name, int version ) : base(jSRuntime, name, version) { } // These are like tables. Declare as many of them as you want. public IndexedSet employee { get; set; } } public class Employee { [Key] public int Id { get; set; } [Required] public string? FirstName { get; set; } [Required] public string? LastName { get; set; } } }
Add the namespace for the IndexedDB in _Import.razor file. [_Import.razor]
Install the Microsoft.AspNetCore.Components.WebAssembly.Server NuGet package in the ASP.NET Core application and add the Blazor WebAssembly application project reference to the ASP.NET Core application. [AspNetCoreApp.csproj]
Add the following configurations the Program.cs file in the ASP.NET Core app to include Blazor WebAssembly. [Program.cs]
.... if (!app.Environment.IsDevelopment()) { app.UseWebAssemblyDebugging(); app.UseExceptionHandler("/Error"); // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. app.UseHsts(); }
app.UseBlazorFrameworkFiles(); app.MapFallbackToFile("index.html"); //app.MapRazorPages(); // Remove this line. app.Run();
To avoid conflicts during publishing between WebAssembly and ASP.NET Core applications, it is necessary to delete the favicon.ico file. By default, both projects create a favicon.ico file, which can lead to conflicts. To resolve this, remove one of the favicon.ico files from the project.
Blazor authentication is implemented to determine who a particular user is. Blazor follows the existing ASP.NET Core authentication mechanisms to show a user’s identity. Follow these steps to implement authentication within Blazor WebAssembly:
Create a Blazor WebAssembly app with individual user account authentication in Visual Studio 2019.
In wwwroot/appsettings.json file, replace the Authority and Client ID placeholders with the proper values taken from the Auth0 dashboard. Note: Use Auth0; it will let you integrate authentication for configuring your application. Refer to this link for how to configure the application. [wwwroot/appsetting.json]
Add CascadingAuthenticationState and AuthorizeRouteView to display the page matching the specified route only if the user is authorized. Otherwise, it redirects to the Login page. [App.razor]
<CascadingAuthenticationState>
<RouterAppAssembly="@typeof(Program).Assembly"> <FoundContext="routeData"> <AuthorizeRouteViewRouteData="@routeData" DefaultLayout="@typeof(MainLayout)"> <Authorizing> <p>Loading...</p> </Authorizing> <NotAuthorized> <p>You're not authorized to reach this page. You need to log in.</p> </NotAuthorized> </AuthorizeRouteView> </Found> <NotFound> <p>Sorry, there's nothing at this address.</p> </NotFound> </Router> </CascadingAuthenticationState>
Create a Razor component to allow the user to log in to be authenticated in the Shared folder. [Shared/LoginControl.razor]
@code{ [Parameter] public string Action { get; set; } }
Now display the authorized content when the app is authorized. If the app is not authorized, display the “Not Authorized” message to the user. [Index.razor]
Blazor authentication is implemented to determine who a particular user is. Blazor follows the existing ASP.NET Core authentication mechanisms to show a user’s identity. Follow these steps to implement authentication with OpenID Connect in Blazor:
Create Blazor application
Create a Blazor Server app and install a NuGet package named “Microsoft.AspNetCore.Authentication.OpenIdConnect” using the NuGet package manager.
Add OIDC and authentication configuration
Add OpenID Connect and cookie authentication service configuration to the Blazor Server app in the Startup.cs file. [Startup.cs]
using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Authentication.OpenIdConnect; using Microsoft.IdentityModel.Tokens;