PrimusSaaS.Documents
2.0.0
dotnet add package PrimusSaaS.Documents --version 2.0.0
NuGet\Install-Package PrimusSaaS.Documents -Version 2.0.0
<PackageReference Include="PrimusSaaS.Documents" Version="2.0.0" />
<PackageVersion Include="PrimusSaaS.Documents" Version="2.0.0" />
<PackageReference Include="PrimusSaaS.Documents" />
paket add PrimusSaaS.Documents --version 2.0.0
#r "nuget: PrimusSaaS.Documents, 2.0.0"
#:package PrimusSaaS.Documents@2.0.0
#addin nuget:?package=PrimusSaaS.Documents&version=2.0.0
#tool nuget:?package=PrimusSaaS.Documents&version=2.0.0
Primus.Documents
Text-to-PDF Document Renderer SDK for .NET applications.
Overview
Primus.Documents is a reusable .NET SDK that renders plain text, Markdown, or HTML content into professional PDF documents. It integrates seamlessly with ASP.NET Core via dependency injection and supports multi-tenant scenarios with built-in self-test capabilities.
Features
- Multiple Content Types: PlainText, Markdown, and HTML input support
- Multi-Tenant Safe: Every operation is scoped to a tenant ID
- Configurable Layout: Page margins, font sizes, headers, footers
- Self-Test Subsystem: Built-in diagnostics with basic/validation/complexity/full modes
- Link-Based Downloads: Generate tokenized short-lived download links
- Security First: Never logs document content body, only metadata
Installation
dotnet add package PrimusSaaS.Documents
Quick Start
1. Register Services
// Program.cs
builder.Services.AddPrimusDocumentRenderer(builder.Configuration, "PrimusDocuments");
2. Configure Options
// appsettings.json
{
"PrimusDocuments": {
"Provider": "Default",
"MaxContentLength": 20000,
"LinkTtl": "00:10:00",
"SelfTestEnabled": true,
"BrandName": "My Company",
"IncludeTimestampInFooter": true,
"IncludeTenantInFooter": true
}
}
3. Inject and Use
public class DocumentController : ControllerBase
{
private readonly IDocumentRenderer _renderer;
public DocumentController(IDocumentRenderer renderer)
{
_renderer = renderer;
}
[HttpPost("render")]
public async Task<IActionResult> Render([FromBody] RenderDocumentRequest request)
{
var pdfBytes = await _renderer.RenderPdfAsync(request);
return File(pdfBytes, "application/pdf", $"{request.Title}.pdf");
}
}
Content Types
PlainText
var request = new RenderDocumentRequest
{
TenantId = "tenant-123",
Title = "My Document",
Content = "This is plain text content.",
ContentType = DocumentContentType.PlainText
};
Markdown
var request = new RenderDocumentRequest
{
TenantId = "tenant-123",
Title = "My Document",
Content = "# Heading\n\nThis is **bold** text.",
ContentType = DocumentContentType.Markdown
};
HTML
var request = new RenderDocumentRequest
{
TenantId = "tenant-123",
Title = "My Document",
Content = "<h1>Hello</h1><p>World</p>",
ContentType = DocumentContentType.Html
};
Self-Test
Run built-in diagnostics to verify the module is working correctly:
var selfTest = serviceProvider.GetRequiredService<IDocumentRendererSelfTest>();
var result = await selfTest.RunAsync(SelfTestMode.Full);
Console.WriteLine($"Success: {result.Success}");
Console.WriteLine($"Passed: {result.PassedTests}/{result.TotalTests}");
Test Modes
| Mode | Description |
|---|---|
Basic |
Smoke tests with minimal valid input |
Validation |
Tests that invalid inputs are rejected |
Complexity |
Tests with long content, unicode, special chars |
Full |
Runs all test modes |
Configuration Options
| Option | Default | Description |
|---|---|---|
Provider |
"Default" |
Rendering provider (QuestPDF-based) |
TempStoragePath |
null |
Path for temp file storage (optional) |
MaxContentLength |
20000 |
Maximum content length in characters |
LinkTtl |
00:10:00 |
TTL for download links |
SelfTestEnabled |
true |
Enable self-test endpoints |
DefaultTitle |
"Document" |
Default title when none provided |
BrandName |
null |
Brand name in footer |
IncludeTimestampInFooter |
true |
Show generation timestamp |
IncludeTenantInFooter |
true |
Show tenant ID in footer |
PageMargin |
50 |
Page margin in points |
BodyFontSize |
12 |
Body text font size |
TitleFontSize |
24 |
Title font size |
Link-Based Downloads
For scenarios where you need a temporary download URL instead of direct streaming:
var linkStore = serviceProvider.GetRequiredService<IDocumentLinkStore>();
// Store PDF and get token
var token = await linkStore.StoreAsync(tenantId, title, pdfBytes, TimeSpan.FromMinutes(10));
// Later: retrieve by token
var doc = await linkStore.RetrieveAsync(token);
if (doc != null)
{
return File(doc.PdfBytes, "application/pdf");
}
Security
⚠️ This module never logs document Content body — only metadata:
- TenantId
- ContentType
- ContentLength
- Operation outcome
- PDF size
This ensures no sensitive document content appears in logs.
Requirements
- .NET 6.0, 7.0, or 8.0
- QuestPDF Community License (automatically configured)
License
MIT License - see LICENSE for details.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 is compatible. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. 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. |
-
net6.0
- Markdig (>= 0.34.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 7.0.0)
- Microsoft.Extensions.Logging.Abstractions (>= 7.0.0)
- Microsoft.Extensions.Options (>= 7.0.0)
- Microsoft.Extensions.Options.ConfigurationExtensions (>= 7.0.0)
- QuestPDF (>= 2024.3.0)
-
net7.0
- Markdig (>= 0.34.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 7.0.0)
- Microsoft.Extensions.Logging.Abstractions (>= 7.0.0)
- Microsoft.Extensions.Options (>= 7.0.0)
- Microsoft.Extensions.Options.ConfigurationExtensions (>= 7.0.0)
- QuestPDF (>= 2024.3.0)
-
net8.0
- Markdig (>= 0.34.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 7.0.0)
- Microsoft.Extensions.Logging.Abstractions (>= 7.0.0)
- Microsoft.Extensions.Options (>= 7.0.0)
- Microsoft.Extensions.Options.ConfigurationExtensions (>= 7.0.0)
- QuestPDF (>= 2024.3.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
v2.0.0:
- Standardized Framework Release.
- Renamed all packages to PrimusSaaS.* namespace.
- Synchronized versions across the entire suite.
- Enhanced metadata and fixed consistency issues.