SiLA2.Frontend.Razor 10.2.2

dotnet add package SiLA2.Frontend.Razor --version 10.2.2
                    
NuGet\Install-Package SiLA2.Frontend.Razor -Version 10.2.2
                    
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="SiLA2.Frontend.Razor" Version="10.2.2" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="SiLA2.Frontend.Razor" Version="10.2.2" />
                    
Directory.Packages.props
<PackageReference Include="SiLA2.Frontend.Razor" />
                    
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 SiLA2.Frontend.Razor --version 10.2.2
                    
#r "nuget: SiLA2.Frontend.Razor, 10.2.2"
                    
#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 SiLA2.Frontend.Razor@10.2.2
                    
#: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=SiLA2.Frontend.Razor&version=10.2.2
                    
Install as a Cake Addin
#tool nuget:?package=SiLA2.Frontend.Razor&version=10.2.2
                    
Install as a Cake Tool

SiLA2.Frontend.Razor

Blazor-Based Web Frontend Components for SiLA2 Servers

Package SiLA2.Frontend.Razor
Version 10.0.0
Framework .NET 10
License MIT
Repository https://gitlab.com/SiLA2/sila_csharp
Wiki https://gitlab.com/SiLA2/sila_csharp/-/wikis/home

Overview

SiLA2.Frontend.Razor is an optional web frontend extension for SiLA2 servers that provides pre-built Blazor Server components for server introspection, monitoring, and management. This module enables developers to quickly add professional web UI capabilities to their SiLA2 laboratory automation servers.

Built on Blazor Server with SignalR, the frontend supports real-time server monitoring with automatic UI updates via server-push technology. The module includes ready-to-use components for displaying server information, feature definitions, user management, and security settings.

Key Benefits:

  • Add a web UI to your SiLA2 server in minutes
  • Pre-built components for common server management tasks
  • Real-time monitoring with automatic UI updates via SignalR
  • Modern Bootstrap styling with Blazor Bootstrap integration
  • Authentication and user management integration
  • No client-side compilation required (Blazor Server)

Key Features

  • Pre-Built Razor Components

    • ServerInformationComponent - Display server metadata, UUID, version, and connection details
    • ServerFeaturesComponent - List all implemented features with interactive command/property execution
    • UserManagementComponent - Manage users, roles, and permissions (requires SiLA2.Authentication)
    • SecurityComponent - View security settings and certificate information
  • Server Data Services

    • IServerDataService - Query server metadata and feature definitions via gRPC
    • IConnectionViewModelProvider - Manage connection view models for UI binding
    • ICommandPayloadProvider - Dynamic command payload construction for generic execution
  • Real-Time Capabilities

    • SignalR-based server-push for live updates
    • Observable property monitoring with automatic UI refresh
    • Observable command execution with progress tracking
  • Modern UI

    • Blazor Bootstrap integration for responsive design
    • Bootstrap Icons for visual elements
    • Customizable CSS styling
  • File Transfer Support

    • JavaScript interop for file upload/download
    • Integration with SiLA2 FileTransfer feature

Installation

Install the NuGet package in your Blazor Server application:

# Package Manager Console
Install-Package SiLA2.Frontend.Razor

# .NET CLI
dotnet add package SiLA2.Frontend.Razor

Dependencies (automatically installed):

  • SiLA2.Core (>= 10.0.0)
  • SiLA2.Client (>= 10.0.0)
  • SiLA2.Communication (>= 10.0.0)
  • SiLA2.Authentication (>= 10.0.0)
  • Blazor.Bootstrap (>= 3.5.0)

Important: This package is designed for Blazor Server applications, not Blazor WebAssembly.

Quick Start

1. Configure Services in Program.cs

using SiLA2.Frontend.Razor.Services;
using SiLA2.Utils.gRPC;
using SiLA2.Utils.Config;

var builder = WebApplication.CreateBuilder(args);

// Add Blazor Server services
builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor();

// Add Blazor Bootstrap
builder.Services.AddBlazorBootstrap();

// Add SiLA2 Frontend services
builder.Services.AddSingleton<IGrpcChannelProvider, GrpcChannelProvider>();
builder.Services.AddScoped<IServerDataService, ServerDataService>();
builder.Services.AddScoped<ICommandPayloadProvider, CommandPayloadProvider>();

// Configure server connection
var serverConfig = new ServerConfig(
    name: "My SiLA2 Server",
    uuid: Guid.Parse("12345678-1234-1234-1234-123456789abc"),
    fqhn: "localhost",
    port: 50051);
builder.Services.AddSingleton<IServerConfig>(serverConfig);

var app = builder.Build();

// Configure HTTP pipeline
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();

// Map Blazor endpoints
app.MapBlazorHub();
app.MapFallbackToPage("/_Host");

app.Run();

2. Create _Host.cshtml Page

Create Pages/_Host.cshtml:

@page "/"
@using Microsoft.AspNetCore.Components.Web
@namespace YourNamespace.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@{
    Layout = null;
}

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <base href="~/" />
    <title>SiLA2 Server Frontend</title>

    
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css"
          rel="stylesheet" />
    <link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.3/font/bootstrap-icons.css"
          rel="stylesheet" />

    
    <link href="_content/Blazor.Bootstrap/blazor.bootstrap.css" rel="stylesheet" />

    <component type="typeof(HeadOutlet)" render-mode="Server" />
</head>
<body>
    <component type="typeof(App)" render-mode="Server" />

    <div id="blazor-error-ui">
        An error has occurred. This application may no longer respond until reloaded.
        <a href="" class="reload">Reload</a>
        <a class="dismiss">🗙</a>
    </div>

    
    <script src="_framework/blazor.server.js"></script>

    
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js"></script>

    
    <script src="_content/Blazor.Bootstrap/blazor.bootstrap.js"></script>
</body>
</html>

3. Create a Razor Page Using Components

Create Pages/Index.razor:

@page "/"

<h1>SiLA2 Server Dashboard</h1>

<ServerInformationComponent></ServerInformationComponent>

Create Pages/Features.razor:

@page "/features"

<h1>Server Features</h1>

<ServerFeaturesComponent></ServerFeaturesComponent>

4. Configure _Imports.razor

Create _Imports.razor to import necessary namespaces:

@using Microsoft.AspNetCore.Components.Web
@using Microsoft.AspNetCore.Components.Forms
@using BlazorBootstrap
@using SiLA2.Frontend.Razor

5. Run Your Application

dotnet run

Navigate to https://localhost:5001 to see your SiLA2 server web frontend.

Pre-Built Razor Components

ServerInformationComponent

Displays server metadata retrieved from the SiLAService core feature.

Usage:

<ServerInformationComponent></ServerInformationComponent>

Displays:

  • Server Name
  • Server UUID
  • Connection details (host:port)
  • Server Description
  • Server Type
  • Server Version
  • Vendor URL

Dependencies:

  • IServerDataService (injected)
  • IServerConfig (injected)
  • IGrpcChannelProvider (injected)

ServerFeaturesComponent

Interactive component that lists all implemented features with the ability to execute commands and query properties.

Usage:

<ServerFeaturesComponent></ServerFeaturesComponent>

Features:

  • Lists all server features with fully qualified identifiers
  • Displays feature descriptions
  • Shows all commands and properties
  • Interactive "Get" buttons for properties (unobservable and observable)
  • Interactive "Run" buttons for commands (unobservable and observable)
  • Dynamic parameter input for commands (supports String, Integer, Real, Boolean, Date, Time, Timestamp, List, Structure)
  • JSON output display for responses
  • Cancel functionality for observable properties/commands
  • Error handling with modal dialogs

Dependencies:

  • IServerDataService (injected)
  • IDynamicMessageService (injected)
  • ICommandPayloadProvider (injected)

Example Command Execution:


<ServerFeaturesComponent></ServerFeaturesComponent>

The component dynamically generates input fields based on command parameter types and executes commands via gRPC.

UserManagementComponent

Comprehensive user administration interface (requires SiLA2.Authentication module).

Usage:

@using SiLA2.Frontend.Razor

<UserManagementComponent></UserManagementComponent>

Features:

  • Create new users with login, password, and role
  • Edit existing users (update password and role)
  • Delete users (except system Admin)
  • Password strength indicator
  • Role management (Admin, Standard)
  • Toast notifications for success/error messages
  • Responsive Bootstrap UI

Dependencies:

  • IUserManager (from SiLA2.Authentication)
  • ILogger<UserManagementComponent>

Prerequisites:

// In Program.cs
builder.Services.AddSiLA2Authentication(options =>
{
    options.UseSqlite(configuration.GetConnectionString("DefaultConnection"));
});

// Initialize database
app.Services.EnsureAuthenticationDatabaseCreated();

SecurityComponent

Displays security settings and certificate information.

Usage:

<SecurityComponent></SecurityComponent>

Features:

  • TLS/SSL certificate viewing
  • Security configuration display
  • Certificate expiration warnings

Services

IServerDataService / ServerDataService

Service for querying SiLA2 server metadata and feature definitions via gRPC.

Interface:

public interface IServerDataService
{
    Task<ServerData> GetServerData(string host, int port, bool acceptAnyServerCertificated = true);
    Task<IDictionary<string, Feature>> GetServerFeatures(string host, int port, bool acceptAnyServerCertificated = true);
}

Usage Example:

@inject IServerDataService ServerDataService
@inject IServerConfig ServerConfig

@code {
    private ServerData _serverData;
    private IDictionary<string, Feature> _features;

    protected override async Task OnInitializedAsync()
    {
        // Get server metadata
        _serverData = await ServerDataService.GetServerData(
            ServerConfig.FQHN,
            ServerConfig.Port,
            acceptAnyServerCertificated: true);

        // Get all feature definitions
        _features = await ServerDataService.GetServerFeatures(
            ServerConfig.FQHN,
            ServerConfig.Port,
            acceptAnyServerCertificated: true);
    }
}

Methods:

GetServerData - Retrieves server configuration and information

  • Queries SiLAService feature properties: ServerName, ServerUUID, ServerType, ServerDescription, ServerVendorURL, ServerVersion
  • Returns ServerData object with ServerConfig and ServerInformation

GetServerFeatures - Retrieves all feature definitions

  • Queries Get_ImplementedFeatures to get feature list
  • Calls GetFeatureDefinition for each feature
  • Deserializes XML feature definitions into Feature objects
  • Returns dictionary mapping fully qualified identifier to Feature

ICommandPayloadProvider

Service for constructing dynamic command payloads from user input.

Usage:

@inject ICommandPayloadProvider CommandPayloadProvider

@code {
    private IDictionary<Tuple<string, string, string>, string> _parameterMap;

    private IDictionary<string, object> GetPayload(FeatureCommand command, Feature feature)
    {
        return CommandPayloadProvider.GetPayloadMap(_parameterMap, command, feature);
    }
}

This service handles conversion of user input strings to appropriate protobuf message types based on parameter definitions.

IConnectionViewModelProvider

Service for managing connection view models in the UI.

Usage:

@inject IConnectionViewModelProvider ConnectionViewModelProvider

@code {
    private ConnectionViewModel _viewModel = ConnectionViewModelProvider.CreateViewModel(host, port);
}

Complete Integration Example

Here's a complete example showing Program.cs configuration with all required services:

using SiLA2.Frontend.Razor.Services;
using SiLA2.Utils.gRPC;
using SiLA2.Utils.Config;
using SiLA2.Communication.Services;
using SiLA2.Authentication.Extensions;
using Microsoft.EntityFrameworkCore;

var builder = WebApplication.CreateBuilder(args);

// Blazor Server configuration
builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor();
builder.Services.AddBlazorBootstrap();

// SiLA2 Authentication (optional)
builder.Services.AddSiLA2Authentication(options =>
{
    options.UseSqlite(builder.Configuration.GetConnectionString("DefaultConnection"));
});

// SiLA2 Frontend services
builder.Services.AddSingleton<IGrpcChannelProvider, GrpcChannelProvider>();
builder.Services.AddScoped<IServerDataService, ServerDataService>();
builder.Services.AddScoped<ICommandPayloadProvider, CommandPayloadProvider>();
builder.Services.AddScoped<IDynamicMessageService, DynamicMessageService>();
builder.Services.AddScoped<IPayloadFactory, PayloadFactory>();
builder.Services.AddScoped<IDynamicAssemblyBuilder, DynamicAssemblyBuilder>();

// Server configuration
var serverConfig = new ServerConfig(
    builder.Configuration["ServerConfig:Name"],
    Guid.Parse(builder.Configuration["ServerConfig:UUID"]),
    builder.Configuration["ServerConfig:FQHN"],
    int.Parse(builder.Configuration["ServerConfig:Port"]));
builder.Services.AddSingleton<IServerConfig>(serverConfig);

var app = builder.Build();

// Configure pipeline
if (!app.Environment.IsDevelopment())
{
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();

// Initialize authentication database (if using SiLA2.Authentication)
app.Services.EnsureAuthenticationDatabaseCreated();

// Map Blazor endpoints
app.MapBlazorHub();
app.MapFallbackToPage("/_Host");

app.Run();

appsettings.json:

{
  "ServerConfig": {
    "Name": "Temperature Controller Server",
    "UUID": "a7c9e3d2-4f1a-4b5c-8e3d-1a2b3c4d5e6f",
    "FQHN": "localhost",
    "Port": 50051
  },
  "ConnectionStrings": {
    "DefaultConnection": "Data Source=authentication.db"
  }
}

Real-Time Updates with SignalR

Blazor Server uses SignalR for real-time communication between server and browser. The frontend components leverage this for live monitoring.

Observable Property Monitoring

@inject IDynamicMessageService DynamicMessageService
@inject IGrpcChannelProvider GrpcChannelProvider

@code {
    private async Task MonitorTemperature(Feature feature, FeatureProperty property)
    {
        var channel = await GrpcChannelProvider.GetChannel(ServerConfig.FQHN, ServerConfig.Port, true);
        var asyncEnumerable = DynamicMessageService.SubcribeObservableProperty(
            property.Identifier, channel, feature);

        await InvokeAsync(async () =>
        {
            var enumerator = asyncEnumerable.GetAsyncEnumerator();
            while (await enumerator.MoveNextAsync())
            {
                // Update UI automatically
                _currentValue = enumerator.Current;
                StateHasChanged();  // Trigger UI refresh
            }
        });
    }
}

Key Pattern:

  • InvokeAsync() ensures UI updates happen on the correct thread
  • StateHasChanged() triggers Blazor to re-render the component
  • SignalR automatically pushes updates to the browser

Observable Command Execution

@code {
    private async Task ExecuteObservableCommand(FeatureCommand command, Feature feature)
    {
        var channel = await GrpcChannelProvider.GetChannel(ServerConfig.FQHN, ServerConfig.Port, true);
        var payloadMap = CommandPayloadProvider.GetPayloadMap(_parameterMap, command, feature);

        var result = DynamicMessageService.ExecuteObservableCommand(
            command.Identifier, channel, feature, payloadMap);

        await InvokeAsync(async () =>
        {
            var enumerator = result.Item2.GetAsyncEnumerator();
            while (await enumerator.MoveNextAsync())
            {
                // Show progress updates
                _progressInfo.Add(JsonConvert.SerializeObject(enumerator.Current));
                StateHasChanged();

                if (enumerator.Current.CommandStatus == ExecutionInfo.Types.CommandStatus.FinishedSuccessfully)
                {
                    break;
                }
            }

            // Get final result
            var finalResult = DynamicMessageService.GetObservableCommandResult(
                result.Item1.CommandExecutionUUID, command.Identifier, channel, feature, result.Item4);
            _finalResponse = JsonConvert.SerializeObject(finalResult);
            StateHasChanged();
        });
    }
}

Creating Custom Pages

You can create custom pages that use the pre-built components or query server data directly.

Example: Custom Dashboard

@page "/dashboard"
@using SiLA2.Frontend.Razor.Services
@inject IServerDataService ServerDataService
@inject IServerConfig ServerConfig

<h1>Server Dashboard</h1>

<div class="row">
    <div class="col-md-6">
        <ServerInformationComponent></ServerInformationComponent>
    </div>
    <div class="col-md-6">
        <div class="card">
            <div class="card-header">Custom Metrics</div>
            <div class="card-body">
                <p>Feature Count: @_featureCount</p>
                <p>Server Status: @_serverStatus</p>
            </div>
        </div>
    </div>
</div>

@code {
    private int _featureCount;
    private string _serverStatus = "Unknown";

    protected override async Task OnInitializedAsync()
    {
        try
        {
            var features = await ServerDataService.GetServerFeatures(
                ServerConfig.FQHN, ServerConfig.Port, true);
            _featureCount = features.Count;
            _serverStatus = "Online";
        }
        catch
        {
            _serverStatus = "Offline";
        }
    }
}

Working Example: Temperature Controller Web Frontend

A complete working example is available in the repository:

Location: src/Examples/TemperatureController/SiLA2.Temperature.Server.App.Webfrontend

To Run:

dotnet run --project src/Examples/TemperatureController/SiLA2.Temperature.Server.App.Webfrontend/SiLA2.Temperature.Server.App.Webfrontend.csproj

URL: https://localhost:5011

Features Demonstrated:

  • Server information display
  • Feature listing with interactive execution
  • Real-time temperature monitoring
  • Observable command execution with progress tracking
  • AnIML data visualization
  • File transfer (upload/download)
  • User management
  • Authentication integration

Key Files:

  • Pages/Index.razor - Dashboard with ServerInformationComponent
  • Pages/Features.razor - Feature explorer with ServerFeaturesComponent
  • Pages/Temperature.razor - Custom temperature monitoring page
  • Pages/UserManagement.razor - User administration
  • Program.cs - Complete service configuration

Authentication Integration

The UserManagementComponent requires SiLA2.Authentication module.

Setup:

// In Program.cs
builder.Services.AddSiLA2Authentication(options =>
{
    options.UseSqlite(configuration.GetConnectionString("DefaultConnection"));
    // or
    options.UseSqlServer(configuration.GetConnectionString("SqlServerConnection"));
});

var app = builder.Build();

// Initialize database
app.Services.EnsureAuthenticationDatabaseCreated();

Protect Pages with Authorization:

@page "/admin"
@attribute [Authorize(Roles = "Admin")]

<h1>Admin Dashboard</h1>

<UserManagementComponent></UserManagementComponent>

Authentication Configuration:

// Add authentication middleware
app.UseAuthentication();
app.UseAuthorization();

Styling and Customization

Blazor Bootstrap Theming

The frontend uses Blazor Bootstrap 3.5.0, which provides modern Bootstrap 5 components.

Custom CSS:

Create wwwroot/css/site.css:

/* Custom primary color for SiLA2 */
:root {
    --sila-primary: #0F3052;
    --sila-secondary: #6c757d;
}

.btn-custom-primary {
    background-color: var(--sila-primary);
    border-color: var(--sila-primary);
    color: white;
}

.btn-custom-primary:hover {
    background-color: #0a2340;
    border-color: #0a2340;
}

.header {
    color: var(--sila-primary);
}

Component Parameter Customization

Pre-built components can be styled via CSS without modifying component code:

<style>
    .table-striped tbody tr:nth-of-type(odd) {
        background-color: rgba(0,0,0,.02);
    }

    .featurerow {
        background-color: #f8f9fa;
        font-weight: bold;
    }
</style>

<ServerFeaturesComponent></ServerFeaturesComponent>

Layout Templates

Create a custom layout in Shared/MainLayout.razor:

@inherits LayoutComponentBase

<div class="page">
    <div class="sidebar">
        <NavMenu />
    </div>

    <main>
        <div class="top-row px-4">
            <h3>SiLA2 Server Management</h3>
        </div>

        <article class="content px-4">
            @Body
        </article>
    </main>
</div>

Additional Resources

Contribution

It's Open Source (License: MIT) - feel free to use or contribute!

License

MIT License - see LICENSE for details.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  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
10.2.2 45 2/12/2026
10.2.1 113 1/25/2026
10.2.0 216 12/23/2025
10.1.0 175 11/29/2025
10.0.0 328 11/11/2025
9.0.4 233 6/25/2025
9.0.3 177 6/21/2025
9.0.2 193 1/6/2025
9.0.1 207 11/17/2024
9.0.0 204 11/13/2024
8.1.2 206 10/20/2024
8.1.1 281 8/31/2024
8.1.0 318 2/11/2024
8.0.0 628 11/15/2023
7.5.4 272 10/27/2023
7.5.3 427 7/19/2023
7.5.2 331 7/3/2023
7.5.1 330 6/2/2023
7.4.6 297 5/21/2023
7.4.5 317 5/7/2023
Loading failed