NETReporter.Client 3.8.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: `reportFooter` takes the new optional `"pinToBottom": true`. The report footer then fills the rest of the last page and lies at its bottom edge (above `pageFooter`) instead of right after the content, so the signature block of a delivery note or an invoice is always at the bottom of the last page; when it does not fit under the content, it moves as a whole to a new page and lies at its bottom. PDF, SVG and the image formats lay it out with QuestPDF `ExtendVertical().AlignBottom().PreventPageBreak()`; HTML and JSON have no pages and keep it right after the content. `pinToBottom` on another section is ignored with the warning `NRP013`, a value that is not a bool is the error `NRP014`. `SectionNode.PinToBottom` is new. - Templates: page sections by data item. `pageHeader`, `pageFooter`, `pageBackground` and `pageOverlay` take the new optional `perPage` (`source`, `as`, optional `filter` and `sortBy`, like `repeat`): page N gets the N-th item of the source under the alias, `loop` has its order and count, and a page without an item has no section. Until now a page section was composed once for the whole document from the root data, so a document with one item per page (labels, certificates with tear-off stubs in the footer) could not show the item of the page in the footer. PDF, SVG and the image formats compose the section for every page (`PerPageSectionComponent`, a QuestPDF dynamic component; `page.number` and `page.total` are the real ones there), HTML and JSON have no pages and use the item of the first page. `perPage` on another section is ignored with the warning `NRP013`, a missing `source` or `as` is an error at `$.<section>.perPage.*`. The data contract treats the fields of the item as fields of the collection (`$.Items[*].Name`), the binding diagnostics of the pages are reported once. `SectionNode.PerPage` and `TemplateRuntimeEngine.RenderSection` are new. - Template schema: `template-schema.json` describes the properties of a section next to `root` in the new list `sectionProperties`, each with the sections it belongs to (`sections`): `perPage` (`source`, `as`, `filter`, `sortBy`) for the page sections and `pinToBottom` (bool) for `reportFooter`. `TemplateSchema.SectionProperties` and `TemplateSchema.GetSectionProperties(section)` are new. The JSON schema of the template editor takes the section properties from it instead of its own copy. - Template editor: section properties. A selected section offers its properties from the schema in the properties panel: `perPage` on the page sections (`pageHeader`, `pageFooter`, `pageBackground`, `pageOverlay`; *Load items from the schema* fills `source`, `as`, `filter` and `sortBy`) and the `pinToBottom` check box on `reportFooter`. The JSON of the section in the panel is checked against the schema of the section (`JsonEditorSchemas.ForSection`, `TemplateJsonSchemaBuilder.BuildSectionSchema`). The Data panel, the `{{` suggestions and the context of the expression assistant know the item alias of `perPage` in the nodes of the section (`DataBindingPaths.ResolveScopes`), as they know the alias of `repeat`. The AI assistant knows `perPage` and `pinToBottom` from its cheat sheets and the schema digest. The HTML preview keeps a pinned report footer right after the content, the PDF and image previews show it at the bottom. - Template editor fix: saving the properties of a section or of the template root (*Save node*, the properties panel) wrote `"id"` and `"type"` (`section_pageFooter`/`Section`, `$`/`Template`) into the section object or the root of the template. The library ignored them, but the JSON editor marked them as unknown properties. Sections and the template root no longer get them (`EditableTreeNode.IsStructural`). - Template editor, ReportServer web UI and account pages: a page icon (favicon), the blue NR mark of the header, shared as `_content/NetReporter.UiShared/favicon.svg`. The editor had no icon, so the browser asked for `/favicon.ico` outside the path of the application (404); the web UI had the default icon of the Blazor project template (`favicon.png`, removed). 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