PortableDocumentationViewer 1.0.0

dotnet add package PortableDocumentationViewer --version 1.0.0
                    
NuGet\Install-Package PortableDocumentationViewer -Version 1.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="PortableDocumentationViewer" Version="1.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="PortableDocumentationViewer" Version="1.0.0" />
                    
Directory.Packages.props
<PackageReference Include="PortableDocumentationViewer" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add PortableDocumentationViewer --version 1.0.0
                    
#r "nuget: PortableDocumentationViewer, 1.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package PortableDocumentationViewer@1.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=PortableDocumentationViewer&version=1.0.0
                    
Install as a Cake Addin
#tool nuget:?package=PortableDocumentationViewer&version=1.0.0
                    
Install as a Cake Tool

Portable Documentation Viewer

A powerful, portable .NET library for adding interactive documentation viewing capabilities to ASP.NET Core applications. This library provides a complete documentation system with file management, categorization, search functionality, and a beautiful web interface.

Features

  • ๐Ÿ“š Dynamic File Loading: Automatically discovers and loads documentation files from specified directories
  • ๐Ÿ—‚๏ธ Smart Categorization: Organizes documentation files by category with custom icons and display names
  • ๐Ÿ” Powerful Search: Full-text search across file names, display names, and categories
  • ๐Ÿ’พ Intelligent Caching: In-memory caching with configurable expiration and file watching for auto-refresh
  • ๐ŸŽจ Beautiful UI: Clean, responsive web interface with markdown rendering support
  • ๐Ÿ”’ Security Features: Path traversal protection, file size limits, and input validation
  • โšก Performance Optimized: Efficient file scanning, caching, and lazy loading
  • ๐Ÿงฉ Highly Configurable: Extensive configuration options for customization
  • ๐Ÿ“ฑ Mobile Friendly: Responsive design that works on all devices

Quick Start

1. Install the Package

dotnet add package PortableDocumentationViewer

2. Configure Services

Add the documentation services to your Program.cs:

using PortableDocumentationViewer.Extensions;

var builder = WebApplication.CreateBuilder(args);

// Add documentation services
builder.Services.AddDocumentation("docs"); // Specify your docs directory

var app = builder.Build();

// Configure documentation middleware
app.UseDocumentationWithApi("/docs");

// Map controllers (required for documentation endpoints)
app.MapControllers();

app.Run();

3. Create Documentation Structure

Create a docs folder in your project root and add your markdown files:

docs/
โ”œโ”€โ”€ README.md
โ”œโ”€โ”€ API-Reference.md
โ”œโ”€โ”€ Phase1-Setup.md
โ”œโ”€โ”€ Phase2-Implementation.md
โ””โ”€โ”€ Configuration-Guide.md

4. Access Your Documentation

Navigate to /docs/doc-viewer.html in your browser to view the interactive documentation interface.

5. Optional: Enable API Endpoints

The documentation viewer automatically includes API endpoints at /api/docs/. If you need to use them programmatically:

// Configure documentation middleware
app.UseDocumentationWithApi("/docs");

// Map controllers (this enables both viewer and API endpoints)
app.MapControllers();

This enables endpoints like:

  • GET /api/docs/files - Get all documentation files with metadata
  • GET /api/docs/categories - Get files organized by category
  • GET /api/docs/file/{fileName} - Get specific file content
  • POST /api/docs/refresh - Refresh the documentation cache

Note: The documentation viewer works perfectly without these API endpoints for basic file viewing.

Development

Building the Library

To build the library from source:

# Clone or navigate to the project directory
cd PortableDocumentationViewer

# Restore dependencies
dotnet restore

# Build in Debug mode
dotnet build

# Build in Release mode
dotnet build -c Release

Creating NuGet Package

To create a NuGet package from the source:

# Build and pack in Release mode
dotnet pack -c Release

# Pack with specific output directory
dotnet pack -c Release -o ./nupkg

# Pack with specific version (if not set in .csproj)
dotnet pack -c Release -p:PackageVersion=1.0.1

The generated .nupkg file will be created in:

  • Default: bin/Release/ directory
  • Custom: Your specified output directory (e.g., ./nupkg/)

Package Information

The NuGet package includes:

  • Library: PortableDocumentationViewer.dll
  • Static Assets: JavaScript, HTML, and CSS files for the documentation viewer
  • XML Documentation: Complete API documentation
  • Dependencies: Required NuGet package references

Version Management

The project includes automated scripts for easy version management during releases.

Interactive Release Script

Use the comprehensive release script for interactive version management:

PowerShell Interactive (Recommended):

# Interactive console menu - most reliable
.\Scripts\Release-Interactive.ps1

PowerShell Advanced:

# Interactive mode - prompts for version choice
.\Scripts\Release.ps1

# Non-interactive mode
.\Scripts\Release.ps1 -VersionAction patch      # Increment patch version
.\Scripts\Release.ps1 -VersionAction minor      # Increment minor version  
.\Scripts\Release.ps1 -VersionAction major      # Increment major version
.\Scripts\Release.ps1 -VersionAction keep       # Keep current version

Windows Batch:

# Interactive mode only (may have compatibility issues)
.\Scripts\Release-Simple.bat

The interactive scripts provide these options:

  • Keep current version - Use existing version number
  • Increment patch - Bug fixes and small updates (1.0.0 โ†’ 1.0.1)
  • Increment minor - New features, backwards compatible (1.0.0 โ†’ 1.1.0)
  • Increment major - Breaking changes (1.0.0 โ†’ 2.0.0)
  • Custom version - Enter any version number manually

Example Console Output:

========================================
PortableDocumentationViewer Release
========================================

Current Version: 1.0.0

Version Management Options:
  1. Keep current version (1.0.0)
  2. Increment patch version
  3. Increment minor version
  4. Increment major version
  5. Enter custom version
  q. Quit

Select an option (1-5, q): 2
Incrementing patch version: 1.0.0 to 1.0.1
Quick Version Updates

For quick version changes without building:

# Show current version
.\Scripts\Version.ps1 -Action show

# Increment versions
.\Scripts\Version.ps1 -Action patch    # 1.0.0 โ†’ 1.0.1
.\Scripts\Version.ps1 -Action minor    # 1.0.0 โ†’ 1.1.0
.\Scripts\Version.ps1 -Action major    # 1.0.0 โ†’ 2.0.0

# Set specific version
.\Scripts\Version.ps1 -Action set -Version "2.1.0"
Manual Version Management

To update the package version manually, modify the .csproj file:

<PropertyGroup>
  <TargetFramework>net8.0</TargetFramework>
  <PackageVersion>1.0.1</PackageVersion>
</PropertyGroup>

Or specify version during pack:

# Pack with specific version
dotnet pack -c Release -p:PackageVersion=1.0.1

# Pack with version suffix (for pre-release)
dotnet pack -c Release --version-suffix beta1

Build Verification

After building, verify the package contents:

List package contents (if you have NuGet CLI)

nuget list -source "$(Get-Location)\nupkg"

To add

dotnet nuget add source "$(Get-Location)\nupkg" --name LocalPackages

To remove

nuget sources remove -name "LocalPackages"

Or extract and inspect manually The .nupkg file is essentially a ZIP file

Using the Package Locally

If you want to build the NuGet package from source and use it directly in your projects without publishing to NuGet.org:

1. Build the NuGet Package

Navigate to the project directory and build the package:

dotnet pack -c Release -o ./nupkg

This will create a .nupkg file in the ./nupkg directory (e.g., PortableDocumentationViewer.1.0.0.nupkg).

2. Add Local NuGet Source to Your Project

In your target project, add the local package as a NuGet source:

Option A: Reference from build location

# Navigate to your project directory
cd YourProject

# Add the local .nupkg file as a package source
dotnet nuget add source "D:\path\to\PortableDocumentationViewer\nupkg" --name LocalPortableDocs

Option B: Copy to your project's nupkg folder

# Create a nupkg folder in your project (if it doesn't exist)
mkdir nupkg

# Copy the package file to your project
copy "D:\path\to\PortableDocumentationViewer\nupkg\PortableDocumentationViewer.1.0.0.nupkg" .\nupkg\

# Add your local nupkg folder as a source
dotnet nuget add source ".\nupkg" --name LocalPackages
# Or use absolute path
dotnet nuget add source "D:\YourProject\nupkg" --name LocalPackages

Option C: Reference package file directly

You can also reference the package file directly in your project's .csproj file:

<ItemGroup>
  <PackageReference Include="PortableDocumentationViewer" Version="1.0.0" />
</ItemGroup>

Then restore packages from the local source:

# Using local nupkg folder in your project
dotnet restore --source ".\nupkg" --source "https://api.nuget.org/v3/index.json"

# Or using the build location
dotnet restore --source "D:\path\to\PortableDocumentationViewer\nupkg" --source "https://api.nuget.org/v3/index.json"

3. Install the Package

Once the source is added, install the package normally:

dotnet add package PortableDocumentationViewer --version 1.0.0

4. Remove Local Source (Optional)

After installation, you can remove the local source if no longer needed:

dotnet nuget remove source LocalPortableDocs

Tips for Local Development

  • Update Package Version: When rebuilding, increment the version in the .csproj file to avoid caching issues
  • Clear NuGet Cache: If you encounter issues, clear the cache:
    dotnet nuget locals all --clear
    
  • Multiple Projects: You can set up a shared local NuGet feed for multiple projects by using a common directory
  • NuGet.config: For team development, add a NuGet.config file to your solution:
    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
      <packageSources>
        <add key="LocalPackages" value="D:\path\to\local\packages" />
        <add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
      </packageSources>
    </configuration>
    

Configuration

Basic Configuration

builder.Services.AddDocumentationServices(options =>
{
    options.DocsDirectory = "docs";
    options.EnableCaching = true;
    options.EnableFileWatching = true;
    options.CacheDurationMinutes = 30;
    options.FilePatterns = new[] { "*.md", "*.txt" };
    options.EnableSecurity = true;
    options.MaxFileSizeBytes = 10 * 1024 * 1024; // 10MB
});

Advanced Configuration (Legacy Mapping Support)

builder.Services.AddDocumentationServices(options =>
{
    options.DocsDirectory = "documentation";
    options.RecursiveScan = true;
    options.EnableCaching = true;
    options.CacheDurationMinutes = 60;
    
    // Note: Custom mappings are available but currently disabled by default
    // The system now uses simple filename-based display names for cleaner navigation
    // To re-enable custom mappings, modify the DocumentationService methods:
    // GetDisplayName(), GetFileCategory(), GetFileIcon(), GetCategoryIcon()
    
    // Custom display name mappings (currently commented out in service)
    options.DisplayNameMappings = new Dictionary<string, string>
    {
        ["README"] = "Getting Started",
        ["API-Reference"] = "API Documentation",
        ["FAQ"] = "Frequently Asked Questions"
    };
    
    // Custom category mappings (currently commented out in service)
    options.CategoryMappings = new Dictionary<string, string>
    {
        ["Phase*"] = "Tutorial Phases",
        ["API-*"] = "API Documentation", 
        ["*-Guide"] = "Guides",
        ["*-Config*"] = "Configuration"
    };
    
    // Custom icon mappings (currently commented out in service)
    options.IconMappings = new Dictionary<string, string>
    {
        ["README"] = "๐Ÿš€",
        ["API-*"] = "๐Ÿ“ก",
        ["*-Guide"] = "๐Ÿ“–",
        ["Tutorial Phases"] = "๐ŸŽฏ",
        ["Configuration"] = "โš™๏ธ"
    };
});

Using Configuration Files

Add configuration to your appsettings.json:

{
  "Documentation": {
    "DocsDirectory": "docs",
    "EnableCaching": true,
    "EnableFileWatching": true,
    "CacheDurationMinutes": 30,
    "FilePatterns": ["*.md", "*.txt", "*.html"],
    "EnableSecurity": true,
    "MaxFileSizeBytes": 10485760,
    "RecursiveScan": false
  }
}

Note: Display name and category mappings are currently disabled for simplified navigation. Files are displayed using their filename without extension and categorized as "Documentation" by default.

Then load it in your service configuration:

builder.Services.AddDocumentationServices(builder.Configuration);

API Endpoints

The library automatically exposes REST API endpoints when you call app.MapControllers(). These endpoints are available at:

  • GET /api/docs/files - Get all documentation files with metadata
  • GET /api/docs/categories - Get files organized by category
  • GET /api/docs/file/{fileName} - Get specific file content
  • POST /api/docs/refresh - Refresh the documentation cache
  • GET /api/docs/version - Get version information
  • GET /docs - Serve the documentation viewer interface

Note: The documentation viewer at /docs/doc-viewer.html works independently and doesn't require these API endpoints for basic functionality.

Customization

Custom API Base URLs

// Use custom documentation path
app.UseDocumentation("/custom/docs/path");
app.MapControllers();

Note: The API endpoints are currently fixed at /api/docs/. To customize the API path, you would need to modify the controller's [Route("api/docs")] attribute.

JavaScript Configuration

The client-side viewer can be customized:

<script>
document.addEventListener('DOMContentLoaded', () => {
    window.documentViewer = new DocumentationViewer({
        apiBaseUrl: '/custom/api/docs',
        enableBranchSwitcher: false,
        enableSearch: true,
        defaultFile: 'README.md',
        theme: 'dark',
        enableMermaid: true,
        enablePrism: true,
        cacheTimeout: 300000
    });
});
</script>

File Organization

Current Behavior (Simplified)

Files are now displayed using their filename without extension for clean, simple navigation:

  • README.md โ†’ Display: "README", Category: "Documentation"
  • API-Reference.md โ†’ Display: "API-Reference", Category: "Documentation"
  • Configuration-Guide.md โ†’ Display: "Configuration-Guide", Category: "Documentation"

This provides a cleaner, more predictable navigation experience without requiring configuration mappings.

Legacy Automatic Categorization (Available but Disabled)

The previous automatic categorization system is still available in the codebase but currently disabled:

  • Phase1-Setup.md โ†’ Category: "Phase 01", Display: "Phase 1: Setup"
  • API-Reference.md โ†’ Category: "General", Display: "API Reference"
  • Configuration-Guide.md โ†’ Category: "General", Display: "Configuration Guide"

Re-enabling Custom Categories (Advanced)

To restore the previous categorization behavior, modify the DocumentationService.cs file:

  1. GetDisplayName() method: Uncomment the custom mapping logic and title case conversion
  2. GetFileCategory() method: Uncomment the wildcard pattern matching and custom category logic
  3. GetFileIcon() method: Uncomment the custom icon mapping logic
  4. GetCategoryIcon() method: Uncomment the configuration-based icon lookup

The configuration mappings in DocumentationOptions.cs are preserved but commented out for reference.

Custom Categories (When Re-enabled)

Use the CategoryMappings configuration to define custom categorization rules:

options.CategoryMappings = new Dictionary<string, string>
{
    ["Phase*"] = "Tutorial Phases",      // Phase*.md files
    ["API-*"] = "API Documentation",     // API-*.md files
    ["*-Guide"] = "User Guides",         // *-Guide.md files
    ["Config*"] = "Configuration"        // Config*.md files
};

Security Features

The library includes several security features:

  • Path Traversal Protection: Prevents access to files outside the configured directory
  • File Extension Validation: Only allows configured file patterns
  • File Size Limits: Configurable maximum file size to prevent memory issues
  • Input Validation: Sanitizes all user inputs

Performance Features

  • Intelligent Caching: Files are cached in memory with configurable expiration
  • File System Watching: Automatic cache invalidation when files change
  • Lazy Loading: Files are loaded on-demand, not all at startup
  • Efficient Scanning: Optimized directory scanning with pattern matching

Browser Support

The documentation viewer works in all modern browsers:

  • Chrome 60+
  • Firefox 55+
  • Safari 12+
  • Edge 79+

Dependencies

Server-side (.NET)

  • Microsoft.AspNetCore.App (8.0+)
  • Microsoft.Extensions.FileProviders.Embedded

Client-side (Optional)

  • marked.js (for enhanced Markdown rendering)
  • Prism.js (for syntax highlighting)
  • Mermaid.js (for diagram rendering)

The library works without these client dependencies but with reduced functionality.

Troubleshooting

Documentation Files Not Loading

  1. Verify the DocsDirectory path is correct
  2. Check file permissions on the documentation directory
  3. Ensure file patterns match your documentation files
  4. Check application logs for detailed error messages

Caching Issues

  1. Disable caching temporarily: EnableCaching = false
  2. Use the refresh endpoint: POST /api/docs/refresh
  3. Check file watcher permissions if EnableFileWatching = true

Performance Issues

  1. Reduce CacheDurationMinutes for frequently changing files
  2. Set appropriate MaxFileSizeBytes limits
  3. Use RecursiveScan = false for large directory structures
  4. Consider file count limits in very large documentation sets

License

This library is released under the MIT License. See the LICENSE file for details.

Contributing

Contributions are welcome! Please feel free to submit pull requests, report bugs, or suggest features.

Support

For support and questions, please check the documentation or open an issue in the project repository.

Product Compatible and additional computed target framework versions.
.NET 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.0 163 11/8/2025

A complete, portable documentation system for ASP.NET Core applications that provides dynamic file loading, categorization, search, and a beautiful web interface.