NETReporter.Client 3.9.0

NETReporter.Client

Tenký klient pro ReportServer: stejné rozhraní jako knihovna NETReporter, ale report se vykreslí na serveru. Aplikace nemusí nést QuestPDF, Roslyn, OxyPlot ani ZXing; přihlašuje se API tokenem, který si vygenerujete v UI ReportServeru.

Klient implementuje IReportRenderer a ITemplateTools z balíčku NETReporter.Abstractions, takže mezi lokálním a vzdáleným renderem přepíná jen registrace v DI. Kód, který renderuje, se nemění.

Instalace

dotnet nuget add source https://nuget.advisor-soft.com/v3/index.json --name AdvisorSoft
dotnet add package NETReporter.Client

Požadavky: .NET 10. Balíčky NETReporter, NETReporter.Abstractions a NETReporter.Client se vydávají společně se stejnou verzí.

API token

  1. Přihlaste se do UI ReportServeru a otevřete stránku API tokeny.
  2. Zadejte název (a případně dobu platnosti) a token vytvořte. Otevřený text se ukáže jen jednou, server si pamatuje jen hash; uložte ho do tajných hodnot (proměnná prostředí, user secrets, trezor), ne do repozitáře.
  3. Token má stejná práva jako jeho vlastník. Odvolat ho může vlastník i správce; deaktivace vlastníka ho vyřadí hned.

Rychlý start s DI

using Microsoft.Extensions.DependencyInjection;
using NetReporter;

services.AddNetReporterClient(options =>
{
    options.BaseAddress = new Uri("https://reports.example.com/api");   // adresa API včetně předpony cesty
    options.ApiToken = configuration["NetReporter:ApiToken"];           // nrp_…
});

// kdekoli v aplikaci
public sealed class InvoiceService(IReportRenderer renderer)
{
    public async Task<byte[]> CreatePdfAsync(Stream template, Stream data)
    {
        await using var pdf = await renderer.RenderAsync(template, data);
        using var buffer = new MemoryStream();
        await pdf.CopyToAsync(buffer);
        return buffer.ToArray();
    }
}

Nastavení jde číst z konfigurace: services.AddNetReporterClient(configuration) čte sekci NetReporterClient s klíči BaseAddress, ApiToken a Timeout. Chybějící adresa nebo token zastaví aplikaci při startu srozumitelnou chybou.

Bez DI

using NetReporter.Client;

using var http = NetReporterClient.CreateHttpClient(new NetReporterClientOptions
{
    BaseAddress = new Uri("https://reports.example.com/api"),
    ApiToken = Environment.GetEnvironmentVariable("NETREPORTER_API_TOKEN")
});

IReportRenderer renderer = new ReportServerRenderer(http);
ITemplateTools tools = new ReportServerTemplateTools(http);

Co klient umí

  • Render libovolné šablony (ad-hoc) do všech formátů: PDF, HTML, JSON, SVG, WebP, PNG, JPEG, i po stránkách (RenderSvgPagesAsync, RenderWebpPagesAsync, …) a se všemi volbami RenderOptions (PDF/A, přílohy, šifrování, vodoznak, rozlišení…).
  • Diagnostiky bindingů přes RenderOptions.OnBindingDiagnostics a pozorovatele pipeline.
  • Nástroje nad šablonou (ITemplateTools): validace šablony a dat, datový kontrakt a ukázková data.
  • Mimo rozsah: správa uložených šablon, render podle uložené šablony a historie jobů (ty zůstávají v UI a REST API).

Čím se vzdálený render liší od lokálního

  • Soubory z disku se na serveru nenačítají: obrázky, SVG ani podklady PDF z cesty k souboru nefungují (použijte data URI nebo adresu http/https).
  • Server omezuje počet stránek, rozlišení obrazů a velikost příloh; diagnostik bindingů vrací nejvýše 50 různých.
  • RenderOptions.Icons se nepoužije: server vykresluje ikony vlastním katalogem.
  • Pozorovatel pipeline dostane zjednodušené události (parsování proběhlo na serveru).

Chyby

Situace Výjimka
Chyba v šabloně ReportServerException (kód TEMPLATE_VALIDATION_FAILED, Diagnostics s JSON cestami)
Vadné volby ArgumentException (ParamName == "options"), u lokálních kontrol bez volání serveru
Překročený limit stránek RenderPageLimitExceededException
Zrušení volajícím OperationCanceledException
Neplatný, odvolaný nebo prošlý token ReportServerException (AUTH_UNAUTHORIZED)
Server nedostupný nebo překročený Timeout ReportServerException (REPORTSERVER_UNAVAILABLE nebo REPORTSERVER_TIMEOUT)

ReportServerException dědí z InvalidOperationException, takže ji zachytí i kód napsaný pro lokální render. Seznam změn je v souboru CHANGELOG.md v balíčku.

No packages depend on NETReporter.Client.

- Templates: merged table cells. A cell of `rows.cells`, `rows.group.summary.cells` and `totalSummary.cells` takes the new optional `colSpan`: a whole number of at least 1, or a binding evaluated per row (`"{{# i.IsNote ? 4 : 1 }}"` for a note over the full width), so a cell stretches over the next columns, for example the label *Total* over the first three columns of the summary. The span counts the columns of the template, columns hidden by `visibleIf` drop out of it, a span past the end of the row is cut, and the cells of the covered columns are neither evaluated nor drawn. A column covered by a number needs no cell in `rows.cells` (no `NRP022`); a span given by a binding covers nothing in the validation, because it may be 1 in another row. - Templates: header groups. Consecutive visible columns with the same new optional `columns[].headerGroup` (text, a binding is evaluated) get a shared cell above their headers; the header then has two rows and the columns without a group span both. The group has the header style and is always centered. - Templates: merging equal values. A column with the new optional `"mergeEqual": true` merges consecutive data rows with the same cell text into one cell (rowspan) with the text and style of the first row. It merges only within the data rows of one group (a group row and a summary break it) and hierarchically: a run ends where the run of a merged column to the left ends, so the same city in two regions is not merged; a cell that is part of a `colSpan` breaks it too. The debug output (`RenderBindingsAsExpressions`) shows the expressions but merges by the data, as the group key. In PDF, SVG and the image formats a merged cell over a page break repeats its text on every page it reaches; HTML writes `rowspan` and `colspan` and two header rows; the JSON render tree has `rowSpan` on merged cells (only above 1), `headerGroups` on the table (only with groups) and `headerGroup` and `mergeEqual` in the `columns` attribute. - Templates: the new code `NRP047` (`DiagnosticCodes.InvalidTableCellSpan`). Error: `colSpan` below 1, not whole, or a text without a binding (a quoted number gets the hint to write it without quotes); another type is `NRP014`. Warning: a number past the last column (cut) and a cell of a column covered by another cell (never drawn). At run time a binding that does not give a whole number of at least 1 is a warning and the cell does not stretch. - Template schema: `columns[]` describes `headerGroup` (string) and `mergeEqual` (bool), the description of `cells` mentions `colSpan`. - Library: `IRenderSink` has two new default interface methods: `TableHeaderGroup(colIndex, colSpan, style, text)` (the default does nothing, the header of a custom sink stays one row) and `TableCell(colIndex, style, text, colSpan, rowSpan)` for a merged cell (the default calls `TableCell(colIndex, style, text, colSpan)`, so a custom sink gets the following rows without the merged cells; every cell carries its `colIndex`). The PDF table places every cell explicitly (`Row`, `Column`). - Template editor: the table editor has *Header group* and *Merge equal* for every column and *Columns* (`colSpan`, a number or a binding) for the cells of rows and summaries. A column covered by a number shows *Covered by the cell of column …* instead of the inputs and its cell is not written to the JSON (the editor keeps it, so it comes back when the span gets smaller). The data contract reads the fields used in `colSpan` and `headerGroup`, the translation of the assistant translates `headerGroup`, and the cheat sheet of the assistant describes the merged cells. - Data contract: a field read in a `colSpan` binding has the new hint `DataFieldHint.ColumnSpan` (the editor shows *cell column span*), and the generated sample data give it 1, so the sample table stays readable instead of stretching every row. A `NETReporter.Client` older than this version reports the new hint value from the server as unknown. Celý seznam změn: CHANGELOG.md v balíčku a https://dev.azure.com/advsoft/Knihovny/_git/NetReporter?path=/src/NetReporter/CHANGELOG.md

Version Downloads Last updated
3.9.2 4 10/28/2026
3.9.1 1 10/27/2026
3.9.0 8 10/20/2026
3.8.1 3 10/19/2026
3.8.0 3 10/19/2026
3.7.0 3 10/19/2026
3.6.0 4 10/17/2026
3.5.1 4 10/15/2026
3.5.0 4 10/15/2026
3.4.2 4 10/15/2026
3.4.0 4 10/12/2026
3.3.0 4 10/11/2026
3.2.2 4 10/10/2026
3.2.1 4 10/10/2026
3.2.0 4 10/10/2026
3.1.1 4 10/09/2026
3.1.0 4 10/09/2026
3.0.1 4 10/08/2026
3.0.0 4 10/08/2026
2.2.1 5 10/05/2026
2.2.0 4 10/05/2026
2.1.0 4 10/04/2026
2.0.1 4 10/04/2026
2.0.0 4 10/03/2026
1.7.0 4 10/03/2026