Reporting data sources
Reports can bind to object models, DataSets, DataTables, CSV sources, Web APIs, or server-side SQL sources. Object and DataSet sources are built in; CSV, Web API, and SQL are optional providers with their own registration and security requirements.
Built-in data sources
Object data source
Object data sources expose scalar properties, nested objects, and collections to the designer.Insert aggregate
Running total
Insert group
Connect data source
No provider settings defined.
Edit formula
| Item | Formula |
| Description | Select a field, function, or operator to insert it into the formula. |
<Report Data="" Editable PreviewFormats="ReportPreviewFormat.Html | ReportPreviewFormat.Pdf"> <ReportViewer PreviewFormat="ReportPreviewFormat.Html | ReportPreviewFormat.Pdf" DefaultPreviewFormat="ReportPreviewFormat.Html" /> <ReportToolbar> <ReportToolbarGroup> <ReportToolbarPanesMenu /> </ReportToolbarGroup> <ReportToolbarGroup> <ReportToolbarItem Command="ReportCommand.ConnectDataSource" Caption="Data sources" ShowCaption /> <ReportToolbarItem Command="ReportCommand.Reset" Caption="Reset" /> </ReportToolbarGroup> <Div Margin="Margin.IsAuto.FromStart"> <ReportToolbarGroup> <ReportToolbarItem Command="ReportCommand.Design" Caption="Design" ShowCaption /> <ReportToolbarItem Command="ReportCommand.Preview" Caption="Preview" ShowCaption /> </ReportToolbarGroup> </Div> </ReportToolbar> <ReportDataSources> <ReportObjectDataSource Name="Invoice" Data="" /> </ReportDataSources> <ReportPage Name="Invoice"> <ReportHeader Name="Invoice header" Height="84"> <ReportText Text="Object data source" X="30" Y="18" Width="240" Height="24" FontSize="20" Bold FontColor="@ReportColors.Blue" /> <ReportText Text="Customer: {Customer.Name}" X="30" Y="48" Width="240" Height="18" /> <ReportText Text="Invoice: {Header.Number}" X="315" Y="48" Width="180" Height="18" TextAlignment="TextAlignment.End" /> </ReportHeader> <ReportPageHeader Name="Line headers" Height="32"> <ReportText Text="Sku" X="30" Y="8" Width="75" Height="18" Bold /> <ReportText Text="Description" X="120" Y="8" Width="210" Height="18" Bold /> <ReportText Text="Total" X="420" Y="8" Width="90" Height="18" Bold TextAlignment="TextAlignment.End" /> </ReportPageHeader> <ReportDetail Name="Invoice lines" Height="30" DataSource="Invoice.Lines"> <ReportField Field="Sku" X="30" Y="6" Width="75" Height="18" /> <ReportField Field="Description" X="120" Y="6" Width="210" Height="18" /> <ReportField Field="Total" Format="@ReportFormats.Currency()" X="420" Y="6" Width="90" Height="18" /> </ReportDetail> <ReportFooter Name="Totals" Height="45"> <ReportLine X="30" Y="6" Width="480" Height="8" Thickness="1" /> <ReportText Text="Invoice total" X="300" Y="18" Width="105" Height="18" Bold /> <ReportField Field="Header.Total" Format="@ReportFormats.Currency()" X="420" Y="18" Width="90" Height="18" Bold FontColor="@ReportColors.Green" /> </ReportFooter> </ReportPage> </Report>
@code { private readonly InvoiceReportModel invoice = new() { Header = new() { Number = "INV-1001", Total = 1240.50m, }, Customer = new() { Name = "Northwind Traders", }, Lines = [ new() { Sku = "SRV-001", Description = "Implementation workshop", Total = 640.50m }, new() { Sku = "LIC-010", Description = "Reporting module license", Total = 500.00m }, new() { Sku = "SUP-003", Description = "Priority support", Total = 100.00m }, ], }; private sealed class InvoiceReportModel { public InvoiceHeaderModel Header { get; set; } public InvoiceCustomerModel Customer { get; set; } public List<InvoiceLineModel> Lines { get; set; } = []; } private sealed class InvoiceHeaderModel { public string Number { get; set; } public decimal Total { get; set; } } private sealed class InvoiceCustomerModel { public string Name { get; set; } } private sealed class InvoiceLineModel { public string Sku { get; set; } public string Description { get; set; } public decimal Total { get; set; } } }
Detail bands and collections
Assign the detail band data source to a collection path. Fields inside the detail band are then resolved against each collection item.Insert aggregate
Running total
Insert group
Connect data source
No provider settings defined.
Edit formula
| Item | Formula |
| Description | Select a field, function, or operator to insert it into the formula. |
<Report Data="" Editable PreviewFormats="ReportPreviewFormat.Html | ReportPreviewFormat.Pdf"> <ReportViewer PreviewFormat="ReportPreviewFormat.Html | ReportPreviewFormat.Pdf" DefaultPreviewFormat="ReportPreviewFormat.Html" /> <ReportDataSources> <ReportObjectDataSource Name="Invoice" Data="" /> </ReportDataSources> <ReportPage Name="Invoice"> <ReportHeader Name="Invoice header" Height="72"> <ReportText Text="Detail band repeats Invoice.Lines" X="30" Y="18" Width="300" Height="24" FontSize="18" Bold FontColor="@ReportColors.Blue" /> <ReportText Text="{Header.Number} - {Customer.Name}" X="30" Y="45" Width="360" Height="18" /> </ReportHeader> <ReportPageHeader Name="Column headers" Height="32"> <ReportText Text="Sku" X="30" Y="8" Width="75" Height="18" Bold /> <ReportText Text="Description" X="120" Y="8" Width="210" Height="18" Bold /> <ReportText Text="Qty" X="345" Y="8" Width="60" Height="18" Bold TextAlignment="TextAlignment.End" /> <ReportText Text="Total" X="420" Y="8" Width="90" Height="18" Bold TextAlignment="TextAlignment.End" /> </ReportPageHeader> <ReportDetail Name="Invoice lines" Height="30" DataSource="Invoice.Lines"> <ReportField Field="Sku" X="30" Y="6" Width="75" Height="18" /> <ReportField Field="Description" X="120" Y="6" Width="210" Height="18" /> <ReportField Field="Quantity" Format="@ReportFormats.Number( 2 )" X="345" Y="6" Width="60" Height="18" /> <ReportField Field="Total" Format="@ReportFormats.Currency()" X="420" Y="6" Width="90" Height="18" /> </ReportDetail> <ReportFooter Name="Totals" Height="45"> <ReportLine X="30" Y="6" Width="480" Height="8" Thickness="1" /> <ReportField Field="Header.Total" Format="@ReportFormats.Currency()" X="420" Y="18" Width="90" Height="18" Bold FontColor="@ReportColors.Green" /> </ReportFooter> </ReportPage> </Report>
@code { private readonly InvoiceReportModel invoice = new() { Header = new() { Number = "INV-1001", Total = 1240.50m, }, Customer = new() { Name = "Northwind Traders", }, Lines = [ new() { Sku = "SRV-001", Description = "Implementation workshop", Quantity = 1, Total = 640.50m }, new() { Sku = "LIC-010", Description = "Reporting module license", Quantity = 2, Total = 500.00m }, new() { Sku = "SUP-003", Description = "Priority support", Quantity = 1, Total = 100.00m }, ], }; private sealed class InvoiceReportModel { public InvoiceHeaderModel Header { get; set; } public InvoiceCustomerModel Customer { get; set; } public List<InvoiceLineModel> Lines { get; set; } = []; } private sealed class InvoiceHeaderModel { public string Number { get; set; } public decimal Total { get; set; } } private sealed class InvoiceCustomerModel { public string Name { get; set; } } private sealed class InvoiceLineModel { public string Sku { get; set; } public string Description { get; set; } public decimal Quantity { get; set; } public decimal Total { get; set; } } }
DataSet data source
UseReportDataSetDataSource to bind reports to enterprise data sources that expose DataSet or DataTable objects. Set TableName to bind one table directly, or omit it to expose tables as nested data sources.
Insert aggregate
Running total
Insert group
Connect data source
No provider settings defined.
Edit formula
| Item | Formula |
| Description | Select a field, function, or operator to insert it into the formula. |
@using System.Data <Report Editable PreviewFormats="ReportPreviewFormat.Html | ReportPreviewFormat.Pdf"> <ReportViewer PreviewFormat="ReportPreviewFormat.Html | ReportPreviewFormat.Pdf" DefaultPreviewFormat="ReportPreviewFormat.Html" /> <ReportDataSources> <ReportDataSetDataSource Name="Orders" DataSet="" TableName="Orders" /> </ReportDataSources> <ReportPage Name="Orders"> <ReportHeader Name="Orders header" Height="72"> <ReportText Text="DataSet data source" X="30" Y="18" Width="300" Height="24" FontSize="18" Bold FontColor="@ReportColors.Blue" /> <ReportText Text="The Orders table is selected from a DataSet." X="30" Y="45" Width="360" Height="18" /> </ReportHeader> <ReportPageHeader Name="Column headers" Height="32"> <ReportText Text="Order" X="30" Y="8" Width="80" Height="18" Bold /> <ReportText Text="Customer" X="125" Y="8" Width="190" Height="18" Bold /> <ReportText Text="Date" X="330" Y="8" Width="80" Height="18" Bold /> <ReportText Text="Amount" X="420" Y="8" Width="90" Height="18" Bold TextAlignment="TextAlignment.End" /> </ReportPageHeader> <ReportDetail Name="Orders" Height="30" DataSource="Orders"> <ReportField Field="OrderNumber" X="30" Y="6" Width="80" Height="18" /> <ReportField Field="Customer" X="125" Y="6" Width="190" Height="18" /> <ReportField Field="OrderDate" Format="@ReportFormats.Date()" X="330" Y="6" Width="80" Height="18" /> <ReportField Field="Amount" Format="@ReportFormats.Currency()" X="420" Y="6" Width="90" Height="18" TextAlignment="TextAlignment.End" /> </ReportDetail> </ReportPage> </Report>
@code { private readonly DataSet orderData = CreateOrderData(); private static DataSet CreateOrderData() { DataSet dataSet = new( "Sales" ); DataTable orders = new( "Orders" ); orders.Columns.Add( "OrderNumber", typeof( string ) ); orders.Columns.Add( "Customer", typeof( string ) ); orders.Columns.Add( "OrderDate", typeof( DateTime ) ); orders.Columns.Add( "Amount", typeof( decimal ) ); orders.Rows.Add( "SO-1001", "Northwind Traders", new DateTime( 2026, 7, 1 ), 1240.50m ); orders.Rows.Add( "SO-1002", "Contoso Retail", new DateTime( 2026, 7, 3 ), 835.00m ); orders.Rows.Add( "SO-1003", "Fabrikam Parts", new DateTime( 2026, 7, 5 ), 2195.75m ); dataSet.Tables.Add( orders ); return dataSet; } }
CSV data source
The CSV provider turns comma-separated text into a tabular report data source. Use it for exports, static reference data, or files produced by another system, supplied inline or loaded from a local file or remote URL.
NuGet
Install the CSV data-source extension.Install-Package Blazorise.Reporting.DataSources.Csv
Imports
In your main _Imports.razor add:
@using Blazorise.Reporting.DataSources.Csv
Register the provider after the core Reporting services. Calling AddBlazoriseReportingCsvDataSource() without callbacks uses the default HTTP configuration and a 5 MB source limit.
Registration
The optional callbacks configure the HTTP client and decide which remote CSV addresses the application permits.
using Blazorise.Reporting.DataSources.Csv;
builder.Services
.AddBlazorise()
.AddBlazoriseReporting()
.AddBlazoriseReportingCsvDataSource(
httpClient => httpClient.ConfigureHttpClient( client =>
{
client.Timeout = TimeSpan.FromSeconds( 30 );
} ),
options =>
{
options.MaxSourceSize = 5 * 1024 * 1024;
options.ResourceAllowed = uri => uri.Host.Equals( "data.example.com", StringComparison.OrdinalIgnoreCase );
} );
Set ReportCsvDataSource.Source to inline CSV text, a local file path in a server application, or an absolute HTTP or HTTPS URL. The first row supplies field names by default, and the provider infers the field types from the remaining rows.
Declarative CSV
Give the source a name and use that name as the data source of a detail band.@using Blazorise.Reporting.DataSources.Csv <Report> <ReportDataSources> <ReportCsvDataSource Name="Products" Source="https://data.example.com/products.csv" Encoding="utf-8" Delimiter="," HasHeaderRow /> </ReportDataSources> <ReportPage Name="Products"> <ReportDetail Name="Product row" Height="24" DataSource="Products"> <ReportField Field="Name" X="30" Y="3" Width="240" Height="18" /> <ReportField Field="Price" X="285" Y="3" Width="90" Height="18" /> </ReportDetail> </ReportPage> </Report>
Remote source security
HTTP sources are downloaded by the browser in Blazor WebAssembly and therefore follow browser CORS rules. In server applications they are downloaded by the server, so useResourceAllowed to restrict user-controlled URLs. Server registrations disable and reject redirects by default. If the primary HTTP handler is replaced, keep automatic redirects disabled so an allowed address cannot redirect to a blocked destination.
REST / Web API data source
The REST / Web API provider retrieves structured data with read-only HTTP GET requests and exposes a selected response collection as report rows. Use it when report data is available through a browser-accessible or server-to-server API instead of a direct database connection.
NuGet
Install the REST / Web API data-source extension.Install-Package Blazorise.Reporting.DataSources.WebApi
Imports
In your main _Imports.razor add:
@using Blazorise.Reporting.DataSources.WebApi
The provider performs read-only HTTP GET requests and delegates response parsing to registered readers. JSON and XML readers are included, and applications can register additional formats through IReportWebApiResponseReader.
Registration
The designer stores the complete absolute HTTP or HTTPS URL, including its path and query, in the report definition. Pre-registering endpoint names is not required. Use the optionalResourceAllowed callback when the application wants to restrict authors to particular hosts or paths. When it is omitted, server applications allow any public URL, while WebAssembly allows any otherwise valid URL subject to browser rules. Public or anonymously accessible server-side designers should always configure an allowlist; the Blazorise documentation site limits its live example to dummyjson.com.
using Blazorise.Reporting.DataSources.WebApi;
builder.Services
.AddBlazorise()
.AddBlazoriseReporting()
.AddBlazoriseReportingWebApiDataSource( configureOptions: options =>
{
// Optional: omit this callback to allow any public HTTP or HTTPS URL.
options.ResourceAllowed = uri =>
uri.Scheme == Uri.UriSchemeHttps
&& uri.IsDefaultPort
&& string.Equals( uri.Host, "dummyjson.com", StringComparison.OrdinalIgnoreCase );
options.MaximumResponseSize = 5 * 1024 * 1024;
options.RequestTimeout = TimeSpan.FromSeconds( 30 );
} );
Request headers can be entered in the designer as one Name: Value pair per line, or supplied through ReportWebApiDataSource.Headers. The URL, query, and these headers are serialized with the report and are visible to anyone who can read or edit it, so do not place protected API keys, bearer tokens, or other server secrets there. Add protected credentials in ConfigureRequestAsync, where the host can obtain them from server configuration and replace or augment report-defined headers. Because that callback receives the requested URL, add credentials only after matching it to an application-owned allowlist; otherwise an author could send them to another public host.
Response data
Useauto to select a reader from the response content type and content, or select a registered format explicitly. The JSON reader accepts an optional RFC 6901 JSON Pointer such as /items. The XML reader accepts an XPath element selector such as /orders/order. Connect infers the selected data schema and closes the dialog only when the request succeeds. While the request is pending, settings and modal dismissal are disabled so the exact definition being validated is committed on success. Changing a setting clears the previous connection result.
Declarative
Supply the complete endpoint URL, optional request headers, a response format, and the response node that supplies report rows. This example uses the public DummyJSON API.@using Blazorise.Reporting.DataSources.WebApi @using System.Collections.Generic <Report> <ReportDataSources> <ReportWebApiDataSource Name="Products" Url="https://dummyjson.com/products?limit=10&select=id,title,price,category" Headers="" ResponseFormat="@WebApiReportDataSourceFormats.Json" DataSelector="/products" /> </ReportDataSources> <ReportPage Name="Products"> <ReportDetail Name="Product row" Height="24" DataSource="Products"> <ReportField Field="title" X="30" Y="3" Width="240" Height="18" /> <ReportField Field="price" X="285" Y="3" Width="90" Height="18" /> </ReportDetail> </ReportPage> </Report>
@code { private readonly IReadOnlyDictionary<string, string> requestHeaders = new Dictionary<string, string> { ["Accept"] = "application/json", }; }
Security
In Blazor Server andInteractiveServer, requests execute on the server. Reporting therefore rejects localhost, loopback, link-local, private, reserved, and other non-public destinations regardless of ResourceAllowed. It resolves the host again when opening the connection, connects only to a public address, disables proxies, cookies, and automatic redirects, and limits response size, collection size, nesting depth, and request duration. The optional resource policy narrows this boundary; it cannot grant access to a blocked network.
In standalone Blazor WebAssembly and InteractiveWebAssembly, the request executes in the user's browser. Authors may enter any absolute HTTP or HTTPS URL, subject to browser CORS, mixed-content, and authentication rules. A client-side ResourceAllowed callback is useful for product behavior but is not an authorization boundary because users control the browser. The target API must authenticate and authorize each request. Browser applications may use the signed-in user's browser-accessible credentials, but must never contain server credentials or client secrets. In every hosting model, treat editable report definitions as untrusted input and expose read-only reporting endpoints.
SQL data source
The SQL provider connects a server-hosted Report directly to a database and exposes an authorized query result as tabular report data. Use it when the host controls database connections and report authors need governed access to reporting views or queries.
NuGet
Install the SQL data-source extension together with the ADO.NET provider for the target database. This example usesMicrosoft.Data.SqlClient for Microsoft SQL Server; use the corresponding provider, such as Npgsql, for another database.
Install-Package Blazorise.Reporting.DataSources.Sql Install-Package Microsoft.Data.SqlClient
Imports
In your main _Imports.razor add:
@using Blazorise.Reporting.DataSources.Sql
Hosting models
The SQL extension executes in the process that renders the report and is intended for Blazor Server andInteractiveServer components.
Do not register a database connection or place a connection string in a standalone Blazor WebAssembly or InteractiveWebAssembly client. The SQL registration throws on browser runtimes because the component and its data source providers execute inside the browser in those render modes, where secrets are visible to the user and direct database access is not a secure application boundary. Execute the database query in an authenticated server API, return only the authorized rows, and bind those rows with ReportObjectDataSource. A Blazor Web App using InteractiveServer follows the server registration shown below because the Report component continues to execute on the server. With InteractiveAuto, use the API and object data source approach unless the Report is explicitly kept in a server render mode.
Server registration
Register application-owned connection factories and a query authorization policy. The designer lists only these registered connection names, and a report stores the selected logical name while the connection string remains in server configuration. Each factory must return a new connection because Reporting opens and disposes it for each schema or data operation.using Blazorise.Reporting.DataSources.Sql; using Microsoft.Data.SqlClient; HashSet<string> allowedQueries = new( StringComparer.Ordinal ) { ReportingQueries.Sales, }; builder.Services .AddBlazorise() .AddBlazoriseReporting() .AddBlazoriseReportingSqlDataSource( options => { options.Connections["Reporting"] = serviceProvider => { IConfiguration configuration = serviceProvider.GetRequiredService<IConfiguration>(); string connectionString = configuration.GetConnectionString( "Reporting" ) ?? throw new InvalidOperationException( "The Reporting connection string is missing." ); return new SqlConnection( connectionString ); }; options.QueryAllowed = ( connectionName, query ) => string.Equals( connectionName, "Reporting", StringComparison.OrdinalIgnoreCase ) && allowedQueries.Contains( query ); options.MaximumCommandTimeout = 30; } ); public static class ReportingQueries { public const string Sales = """ SELECT OrderNumber, Total FROM Reporting.Sales ORDER BY OrderNumber """; }
Queries are denied when QueryAllowed is not configured or returns false. For ordinary report authors, use an exact allowlist of application-owned SQL. A check such as query.StartsWith("SELECT") is not a security boundary because SQL comments, common table expressions, multiple statements, provider-specific commands, and database functions can still have side effects. An application restricted to trusted SQL authors may deliberately allow every query for a registered connection by returning true; this grants those authors the database identity's full effective permissions, so combine it with a dedicated read-only identity and restricted reporting views. MaximumCommandTimeout is a server-owned upper bound; a report may request a shorter positive timeout but cannot disable or increase that limit.
Security model
SQL settings are part of the report definition and editable reports must be treated as untrusted input. The policy is evaluated for both schema discovery and preview data loading before a connection is opened. SQL data sources provide aTest Connection action that runs server-side schema resolution without changing the report, while Connect or Save changes closes the dialog and commits the connection only after validation succeeds. A denied or failed designer connection remains open and is not committed, and editing an existing connection preserves its previous settings when validation fails. Settings and modal dismissal are disabled during validation so the exact tested definition is the one that can be committed. This fail-closed design prevents a modified or uploaded report definition from selecting an arbitrary connection string or executing an unapproved command. Connection names are also resolved only from the factories registered by the host application.
The allowlist complements database security rather than replacing it. Use a dedicated read-only database identity with access only to reporting views or reporting data, keep dangerous database extensions and operating-system integration disabled, and authenticate and authorize access to the report designer. Data-source failures display a generic warning; the full exception is written to the application logger and supplied to OperationFailed for trusted server-side handling. The SQL provider does not add parameters to report queries, so never concatenate user input into the query text.
Declarative SQL
The connection name and query must pass the server registration policy before Reporting opens a database connection. Use the data source name from report bands and fields.@using Blazorise.Reporting.DataSources.Sql <Report> <ReportDataSources> <ReportSqlDataSource Name="Sales" ConnectionName="Reporting" Query="@ReportingQueries.Sales" CommandTimeout="15" /> </ReportDataSources> <ReportPage Name="Sales"> <ReportDetail Name="Sale" Height="24" DataSource="Sales"> <ReportField Field="OrderNumber" X="30" Y="3" Width="240" Height="18" /> <ReportField Field="Total" X="285" Y="3" Width="90" Height="18" /> </ReportDetail> </ReportPage> </Report>
API
See the documentation below for a complete reference to all of the props and classes available to the components mentioned here.