CoreBlazor 0.1.0-beta

This is a prerelease version of CoreBlazor.
dotnet add package CoreBlazor --version 0.1.0-beta
                    
NuGet\Install-Package CoreBlazor -Version 0.1.0-beta
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="CoreBlazor" Version="0.1.0-beta" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="CoreBlazor" Version="0.1.0-beta" />
                    
Directory.Packages.props
<PackageReference Include="CoreBlazor" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add CoreBlazor --version 0.1.0-beta
                    
#r "nuget: CoreBlazor, 0.1.0-beta"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package CoreBlazor@0.1.0-beta
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=CoreBlazor&version=0.1.0-beta&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=CoreBlazor&version=0.1.0-beta&prerelease
                    
Install as a Cake Tool

<img src="https://github.com/gkukucska/CoreBlazor/blob/main/CoreBlazor.png" width="128" height="128"> CoreBlazor

codecov Build and Test Deploy to Azure

A generic entity framework core UI library written in Blazor using server side rendering.

Feel free to check the demo app in action on this very slow website: https://coreblazor-demo.azurewebsites.net/. In order to showcase the multiple DbContext support, the demo uses two separate databases: a normal and a "sensitive" database. To interact with the sensitive database, please log in with either of the provided users:

  • Reader: can read data
  • Editor: can read, add, and edit data
  • Admin: can read, add, edit and delete data

To edit or delete data, double-click on the specific row in the table view.

This package was inspired by the CoreAdmin library, but it has been completely rewritten with performance, extensibility and security in mind.

Features

  • Generic CRUD operations for any entity
  • Support for navigation properties
  • Server (database) side pagination, sorting, and filtering
  • Customizable UI components for viewing and editing entity properties and entity display
  • Policy based access control
  • Configurability on table (DbSet) level using fluent syntax
  • Multiple DbContext support
  • Custom display and editor components
  • Property-level configuration
  • Hidden properties support
  • Split query optimization

Installation

Prerequisites

  • .NET 8.0 or later
  • Entity Framework Core 8.0 or later
  • BlazorBootstrap for UI components

NuGet Package

dotnet add package CoreBlazor

Quick Start

1. Basic Setup

For the most simple usage, add the following code to your Program.cs file:

builder.Services.AddDbContextFactory<YourDbContext>()
                .AddCoreBlazor();

This will add all required services to the dependency injection container and find all DbSet properties in all registered DbContext. Note that DbContexts must be registered using AddDbContextFactory, and not AddDbContext.

2. Configure the Request Pipeline

Add CoreBlazor to your request pipeline in the Program.cs file:

app.MapRazorComponents<App>()
   .AddInteractiveServerRenderMode()
   .AddCoreBlazor();

3. Configure Routes

In your Routes.razor file, add the CoreBlazor assembly to the router:

<Router AppAssembly="typeof(Program).Assembly"
        AdditionalAssemblies="[typeof(CoreBlazor.WebApplicationExtensions).Assembly]">
    <Found Context="routeData">
        <RouteView RouteData="routeData" DefaultLayout="typeof(Layout.MainLayout)" />
        <FocusOnNavigate RouteData="routeData" Selector="h1" />
    </Found>
</Router>

4. Install BlazorBootstrap

Follow the installation instructions for BlazorBootstrap in server side render mode in App.razor and related files. CoreBlazor uses BlazorBootstrap for its UI components.

Advanced Configuration

You can customize numerous features by using either the fluent API in the AddCoreBlazor method or by providing an instance of the CoreBlazorDbContextOptions<TContext> class. Please note that not all configuration options are available when providing an instance of the configuration class (e.g. authorization).

Configure Multiple DbContexts

CoreBlazor supports multiple DbContext configurations.

builder.Services
    .AddDbContextFactory<DemoDbContext>()
    .AddDbContextFactory<SensitiveDbContext>()
    .AddCoreBlazor()
        .ConfigureContext<DemoDbContext>(options =>
        {
            options.WithTitle("Demo Database")
                   .WithSplitQueries();
        })
        .ConfigureContext<SensitiveDbContext>(options =>
        {
            options.WithTitle("Sensitive Database")
                   .UserCanReadIf(user => user.IsInRole("Admin"));
        });

Context-Level Configuration

Set Context Title

Sets the title displayed in the navigation menu:

options.WithTitle("My Database")
Enable Split Queries

Improve performance for queries with navigation properties:

options.WithSplitQueries()

Note that this setting applies to all DbSets in the context, for individual DbSet configuration, use the WithSplitQueries method on the DbSet options.

Context-Level Access Control

Control who can read the db context information:

options.UserCanReadIf(user => user.IsInRole("Viewer"))

Note that this also disables read, edit, etc. authorizations on individual DbSets if the user is not authorized.

DbSet (Table) level Configuration

Configure individual entity sets using the ConfigureSet method:

.ConfigureContext<DemoDbContext>(options =>
    options.ConfigureSet<Person>(personOptions => 
    {
        personOptions.WithTitle("People")
                     .UserCanReadIf(user => user.Identity.IsAuthenticated)
                     .UserCanCreateIf(user => user.IsInRole("Editor"))
                     .UserCanEditIf(user => user.IsInRole("Editor"))
                     .UserCanDeleteIf(user => user.IsInRole("Admin"));
    }))
Alternative Syntax (Lambda Expression)

In case more than one DbSet of the same type exists in the DbContext, you can also use a lambda expression to specify the DbSet:

.ConfigureSet(context => context.People, personOptions => 
{
    // Configuration here
})

Entity Display Configuration

Display Entity with Custom Component

This component will be used to display the entity when displayed in the grid or during editing, creation of parent entities:

personOptions.WithEntityDisplay<PersonDisplayComponent>()

The component must implement the IEntityDisplayComponent<TEntity> interface.

Display Entity with Lambda Expression

Short hand if the set should be displayed by one of its member properties:

personOptions.WithEntityDisplay(person => person.Name)

Example custom display component:

public class PersonDisplayComponent : ComponentBase, IEntityDisplayComponent<Person>
{
    [Parameter]
    public Person? Entity { get; set; }

    protected override void BuildRenderTree(RenderTreeBuilder builder)
    {
        builder.AddContent(0, $"{Entity?.Name} ({Entity?.Email})");
    }
}

Note that the Parameter attribute is required for the component parameters.

Property Configuration

Hide Properties
personOptions.ConfigureProperty(person => person.Id).Hidden()
             .ConfigureProperty(person => person.CreatedDate).Hidden()
Custom Property Display

This component will be used to display the property when displayed in the grid or during editing, creation of parent entities:

personOptions.ConfigureProperty(person => person.Gender)
             .WithDisplay<GenderDisplayComponent>()

The component must implement the IPropertyDisplayComponent<TProperty> interface.

Display component example:

public class GenderDisplayComponent : ComponentBase, IPropertyDisplayComponent<Person>
{
    [Parameter]
    public object? PropertyValue { get; set; }

    protected override void BuildRenderTree(RenderTreeBuilder builder)
    {
        var gender = PropertyValue as Gender?;
        builder.AddContent(0, gender switch
        {
            Gender.Male => "? Male",
            Gender.Female => "? Female",
            _ => "Unknown"
        });
    }
}
Custom Property Editor

This component will be used to edit the property when editing or creating entities:

imageOptions.ConfigureProperty(image => image.Data)
            .WithDisplay<ImageDisplayComponent>()
            .WithEditor<ImageEditorComponent>()

The component must implement the IPropertyEditorComponent<TEntity, TProperty> interface.

Editor component example:

public class ImageEditorComponent : ComponentBase, IPropertyEditorComponent<Image, byte[]>
{
    [Parameter]
    public byte[]? PropertyValue { get; set; }

    [Parameter]
    public EventCallback<byte[]> PropertyValueChanged { get; set; }

    // Editor implementation
}

Access Control (Security)

DbSet-Level Permissions

Control who can perform operations on specific entity sets:

jobOptions.UserCanReadIf(user => user.Identity.IsAuthenticated)
          .UserCanCreateIf(user => user.IsInRole("Editor") || user.IsInRole("Admin"))
          .UserCanEditIf(user => user.IsInRole("Editor") || user.IsInRole("Admin"))
          .UserCanDeleteIf(user => user.IsInRole("Admin"))
Context-Level Permissions
options.WithTitle("Sensitive Database")
       .UserCanReadIf(user => user.IsInRole("Admin"))

Note that this also disables read, edit, etc. authorizations on individual DbSets if the user is not authorized.

Complete Configuration Example

Here's a comprehensive example showing all configuration options:

builder.Services
    .AddDbContextFactory<DemoDbContext>()
    .AddCoreBlazor()
        .ConfigureContext<DemoDbContext>(options =>
        {
            options.WithTitle("Demo Database")
                   .WithSplitQueries()
                   
                   // Configure Jobs
                   .ConfigureSet<Job>(jobOptions => 
                   {
                       jobOptions.WithEntityDisplay<JobDisplayComponent>()
                                 .ConfigureProperty(job => job.Id).Hidden()
                                 .WithTitle("Jobs");
                   })
                   
                   // Configure People
                   .ConfigureSet<Person>(personOptions => 
                   {
                       personOptions.WithEntityDisplay(person => person.Name)
                                    .ConfigureProperty(person => person.Id).Hidden()
                                    .ConfigureProperty(person => person.JobId).Hidden()
                                    .ConfigureProperty(person => person.Gender)
                                        .WithDisplay<GenderDisplayComponent>()
                                    .WithTitle("People")
                                    .UserCanReadIf(user => user.Identity.IsAuthenticated)
                                    .UserCanCreateIf(user => user.IsInRole("Editor"))
                                    .UserCanEditIf(user => user.IsInRole("Editor"))
                                    .UserCanDeleteIf(user => user.IsInRole("Admin"));
                   })
                   
                   // Configure Images with custom display and editor
                   .ConfigureSet(context => context.Images, imageOptions => 
                   {
                       imageOptions.WithTitle("Profile Images")
                                   .ConfigureProperty(image => image.Data)
                                       .WithDisplay<ImageDisplayComponent>()
                                       .WithEditor<ImageEditorComponent>()
                                   .ConfigureProperty(image => image.Id).Hidden()
                                   .WithEntityDisplay<ImageDataDisplayComponent>();
                   });
        });

Please refer to the CoreBlazorDemo project for a complete working example.

CoreBlazor automatically handles navigation properties:

  • Select related entities from dropdown/modal
  • Display related entity information
  • Automatic foreign key management

Performance Optimization

Split Queries

For entities with multiple navigation properties, use split queries to avoid cartesian explosion:

options.WithSplitQueries()

Server-Side Operations

All pagination, sorting, and filtering operations are performed server-side (in the database) for optimal performance.

UI Features

Grid Features

  • Pagination: Configurable page sizes
  • Sorting: Click column headers to sort
  • Filtering: Type to filter by column values
  • Responsive: Filtering, sorting, and pagination are executed on the database side

CRUD Operations

  • Create: Add new entities with validation
  • Read: View entities in grids and detail views
  • Update: Edit entities with custom editors
  • Delete: Confirm before deletion

Validation

As of now only data annotations are supported for validation.

Authorization Integration

CoreBlazor integrates with ASP.NET Core's built-in authorization:

builder.Services.AddAuthorization()
                .AddScoped<AuthenticationStateProvider, YourAuthProvider>();

Access is controlled through user assertion for specific user roles, which can be either configured using the fluent API or by implementing custom authorization policies.

The custom roles are generated based on the name of the DbContext and the DbSet and the access type (Read, Create, Edit, Delete):

  • Create: "{DbContextName}/{DbSetName}/Create"
  • Read: "{DbContextName}/{DbSetName}/Read"
  • Edit: "{DbContextName}/{DbSetName}/Edit"
  • Delete: "{DbContextName}/{DbSetName}/Delete"
  • Read Info: "{DbContextName}/Info"

Customization

Custom Components

Implement these interfaces for custom components:

  • IEntityDisplayComponent<TEntity> - Custom entity display
  • IPropertyDisplayComponent<TProperty> - Custom property display
  • IPropertyEditorComponent<TEntity, TProperty> - Custom property editor
  • INavigationPathProvider - Custom navigation paths
  • INotAuthorizedComponentProvider - Custom unauthorized access component

Styling

CoreBlazor uses BlazorBootstrap, so you can customize appearance using:

  • Bootstrap themes
  • Custom CSS
  • Bootstrap utility classes

Testing

The project includes comprehensive unit tests:

  • 99+ test cases
  • bUnit for component testing
  • xUnit test framework
  • FluentAssertions for readable assertions
  • NSubstitute for mocking

See the CoreBlazor.Tests project for examples.

Best Practices

  1. Hide ID properties: Always hide technical IDs from users
  2. Custom displays: Provide meaningful entity displays for navigation properties
  3. Access control: Always configure appropriate permissions
  4. Split queries: Enable for entities with multiple navigation properties
  5. Custom editors: Use for complex properties (images, enums, etc.)

Troubleshooting

Routes not found

Ensure CoreBlazor assembly is added to the router's AdditionalAssemblies.

Authorization not working

Check that:

  • AuthenticationStateProvider is registered
  • app.UseAuthorization() is called in the pipeline
  • Authorization policies are configured correctly

Performance issues

  • Enable split queries for complex entities
  • Ensure database indexes on frequently queried columns
  • Check for N+1 query problems

Examples

Check the CoreBlazorDemo project for complete working examples including:

  • Multiple DbContext configuration
  • Custom display components
  • Custom editor components
  • Authorization setup
  • Image handling

Support

For issues and questions:

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.1.0-beta 57 1/19/2026