N2.Documents 2.0.1

dotnet add package N2.Documents --version 2.0.1
                    
NuGet\Install-Package N2.Documents -Version 2.0.1
                    
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="N2.Documents" Version="2.0.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="N2.Documents" Version="2.0.1" />
                    
Directory.Packages.props
<PackageReference Include="N2.Documents" />
                    
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 N2.Documents --version 2.0.1
                    
#r "nuget: N2.Documents, 2.0.1"
                    
#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 N2.Documents@2.0.1
                    
#: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=N2.Documents&version=2.0.1
                    
Install as a Cake Addin
#tool nuget:?package=N2.Documents&version=2.0.1
                    
Install as a Cake Tool

N2.Documents

Document management services using Azure Blob Storage and Azure Table Storage.

Overview

N2.Documents provides a complete document management solution with:

  • Document storage in Azure Blob Storage
  • Document metadata stored in Azure Table Storage
  • Role-based access control
  • Support for private and public documents
  • Document tagging and search capabilities

Installation

Add the N2.Documents package to your project:

dotnet add package N2.Documents

Configuration

appsettings.json

Add the following configuration to your appsettings.json:

{
  "DocumentServiceSettings": {
    "StorageConnectionString": "your-azure-storage-connection-string",
    "ValidRoles": ["ADMIN", "USER", "MANAGER"]
  }
}

Dependency Injection Setup

Register the required services in your Program.cs or Startup.cs:

using N2.Documents;
using N2.Core;

// Register core dependencies
builder.Services.AddSingleton<ILogService, YourLogService>();
builder.Services.AddScoped<IUserContext, YourUserContext>();
builder.Services.AddSingleton<ISettingsService, YourSettingsService>();

// Register document services
builder.Services.AddSingleton<IBlobServiceClient>(sp =>
{
    var settings = sp.GetRequiredService<ISettingsService>();
    var config = settings.GetConfigSettings<DocumentServiceSettings>();
    return new BlobServiceClient(config.StorageConnectionString);
});

builder.Services.AddSingleton<IBinaryStorageService, BlobStorageService>();

builder.Services.AddSingleton<IDocumentRepository>(sp =>
{
    var settings = sp.GetRequiredService<ISettingsService>();
    var config = settings.GetConfigSettings<DocumentServiceSettings>();
    return new AzureDocumentRepository(config.StorageConnectionString);
});

builder.Services.AddScoped<IDocumentService, DocumentService>();

Usage Examples

1. Uploading a Document

public class DocumentController : ControllerBase
{
    private readonly IDocumentService documentService;

    public DocumentController(IDocumentService documentService)
    {
        this.documentService = documentService;
    }

    [HttpPost("upload")]
    public async Task<IActionResult> UploadDocument(IFormFile file)
    {
        using var stream = file.OpenReadStream();

        var documentInfo = new DocumentInformation
        {
            FileName = file.FileName,
            ProcessName = "MyProcess",
            Remarks = "User uploaded document",
            IsEnabled = true,
            Roles = new[] { "USER", "ADMIN" },
            Tags = new[] { "invoice", "2024" },
            DcmiType = AttachmentType.Document
        };

        var (success, document) = await documentService.SaveDocumentAsync(stream, documentInfo);

        if (success)
        {
            return Ok(new { DocumentId = document.PublicId });
        }

        return BadRequest("Failed to save document");
    }
}

2. Searching for Documents

public async Task<IEnumerable<DocumentInformation>> SearchDocuments(string searchTerm)
{
    var userRoles = new[] { "USER", "ADMIN" };
    var documents = await documentService.FindDocumentsAsync(
        search: searchTerm,
        forRoles: userRoles,
        processName: "MyProcess",
        showInactiveDocuments: false
    );

    return documents;
}

3. Retrieving Document Information

public async Task<DocumentInformation> GetDocument(Guid documentId)
{
    var (success, document) = await documentService.GetDocumentInformationAsync(documentId);

    if (!success)
    {
        throw new DocumentNotFoundException($"Document {documentId} not found");
    }

    return document;
}

4. Updating Document Metadata

public async Task<bool> UpdateDocument(Guid documentId, string newRemarks)
{
    var (success, existingDoc) = await documentService.GetDocumentInformationAsync(documentId);

    if (!success)
    {
        return false;
    }

    existingDoc.Remarks = newRemarks;
    existingDoc.Roles = new[] { "ADMIN", "MANAGER" };

    var (updateSuccess, updatedDoc) = await documentService.UpdateDocumentAsync(
        documentId,
        existingDoc
    );

    return updateSuccess;
}

5. Deleting a Document

public async Task<bool> DeleteDocument(Guid documentId)
{
    var (success, message) = await documentService.DeleteDocumentAsync(documentId);

    if (success)
    {
        Console.WriteLine(message); // "Document deleted"
    }

    return success;
}

Key Features

Role-Based Access Control

Documents can be assigned to specific roles. Users can only access documents if:

  • They have one of the assigned roles
  • The document is marked as private and they are the creator
  • They are an administrator

Private vs Public Documents

  • Private documents: Only visible to the creator and administrators
  • Public documents: Visible to all users with the appropriate roles

Document Metadata

Each document includes:

  • PublicId: Unique identifier
  • FileName and Extension: Original file information
  • Roles: Array of roles that can access the document
  • Tags: Array of tags for categorization
  • ProcessName: Associated business process
  • Remarks: Description or notes
  • Created and UploadedBy: Audit information
  • IsEnabled: Soft enable/disable flag
  • IsPrivate: Privacy flag

Best Practices

  1. Always check success flags: All operations return a tuple with a success indicator
  2. Use process names: Group documents by business process for easier management
  3. Leverage tags: Use tags for flexible categorization and filtering
  4. Set appropriate roles: Ensure documents are only accessible to authorized users
  5. Handle errors gracefully: Check for null/empty results and handle accordingly

Dependencies

Required interfaces that must be implemented in your application:

  • ILogService: Logging abstraction
  • IUserContext: Current user information (including PublicId and role checking)
  • ISettingsService: Configuration management

Storage Structure

Documents are stored hierarchically in Azure Blob Storage:

Data/{ProcessName}/{byte1}/{byte2}/{byte3}/{byte4}/{guid}.{extension}

Metadata is stored in Azure Table Storage for fast querying and filtering.

Product Compatible and additional computed target framework versions.
.NET net9.0 is compatible.  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
2.0.1 179 10/13/2025
2.0.0 176 10/13/2025
1.1.0 182 10/13/2025
1.0.10-pre0807 147 8/7/2024