NETReporter.Client 3.4.2

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.

- Template editor (ToDo #191): quick search in the panel *Struktura*. The field *Hledat ve stromu* above the tree (or Ctrl+F outside text fields; the JSON editor keeps its own search) filters the tree while typing: it shows the matching nodes with their path from the root and highlights the match. It searches the node type, the label, the `id`, the whole text (`text`, the spans of a paragraph, the chart title), the named style (`styleRef`, `styles`) and the table columns (header and key), ignoring case and diacritics (`cast` finds `Část`); a match the tree does not show is listed after the node (`id: …`, `styl: …`, `sloupec: …`). Enter or ↓ selects the next match, Shift+Enter or ↑ the previous one (the selection works like a click in the tree: properties, preview, JSON), Esc clears the search and restores the tree as it was, collapsed branches included. The search is only a view: it does not change the template, it is not an undo step, and dragging nodes is off while it is active. The command palette has *Hledat ve stromu*. - Template editor fix (performance): a long template appeared in the tree node by node for tens of seconds (721 nodes took 21 s). The tree was expanded by `ExpandAllAsync` after every render of the page, and the TreeView expands the nodes one by one with an animation. The nodes are now expanded in the data of the tree and without the animation (721 nodes in about 0.3 s, 1,800 nodes in about 0.7 s including the analysis), and the tree is a separate component (`StructureTree`) that renders only when the tree, the errors, the selection or the search change, not with every render of the page. Branches the user collapsed stay collapsed after an edit of the template; a node selected outside the tree (preview, diagnostics, palette) inside a collapsed branch expands it. - Styles and `Line` (ToDo #192): the style of a border line and of a line. The border objects (`border`, `borderTop`, `borderRight`, `borderBottom`, `borderLeft`) have the new member `lineStyle` and the node `Line` the new property `lineStyle` (the new enum `LineStyle`: `Solid` (default), `Dashed`, `Dotted`, `Double`; validated like the other enums, `NRP015`). Every side can have its own style. The dash length follows the width: `Dashed` is a dash of 3× and a gap of 2× the width (at least 3 and 2 pt), `Dotted` squares of the width with a gap of the width (at least 1 pt), `Double` two lines of a third of the width with a gap of a third, so it takes the same space as a solid line. QuestPDF draws only solid borders, so the PDF draws a dashed, dotted or double side with an SVG layer over the content (`LineStyles` in the QuestPDF renderer): it lies like the solid border (centered on the edge, it takes no space in the layout), four equal sides are one rectangle, and the layer is repeated on every page a broken box spans. The SVG and image outputs come from the same document. A border with solid sides only is drawn as before, so existing PDFs do not change. The `Line` uses the dash pattern of QuestPDF (`LineDashPattern`). The HTML output writes the CSS `border-style`, the JSON output has `lineStyle` in the border and in the attributes of `Line`. The template editor offers `lineStyle` in the property grid (the style of a node, the named styles, the `Line` node) from the schema; the assistant cheat sheets mention it and the schema digest of the styles lists the enum values of the nested members. 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