Skip to content

Documents Providers – Guide & Recipes (one-pager)

Use this page to choose a provider fast, wire it up, and overview of all the available providers. Deep dives live in the provider-specific guides.*


See for more details


Quick map of the providers (the big picture)

Provider Kind “Groups” mean… Where data lives Best for / notes
FileDocumentRepository Grouped OS folders Local / network filesystem Dev/test, simple deployments. Stores *.metadata.json next to files.
DHI.Services.Provider.MCLite.DocumentRepository Grouped MCLite folders DB (PostgreSQL/SQL Server/SQLite) DB-backed, metadata filtering (AND), optional XML metadata search, thumbnails.
DHI.Services.Provider.MIKECloud.GroupedDocumentRepository Grouped MIKECloud Projects/Subprojects MIKECloud datasets Cloud projects; group listing & metadata filter supported.
DHI.Services.Provider.MIKECloud.DocumentRepository Flat n/a MIKECloud datasets Simplest MIKECloud integration (no grouped listing/filter endpoints).

Grouped = supports group APIs (GetByGroup, GetFullNames, /api/documents/{id|fullnames}?group=…). Route encoding: /| and ||| in URLs.


Which one should I pick?

  • Local dev / offline / trivial hostingFile
  • DB-backed with search & foldersMCLite
  • MIKECloud project(s) with folders & searchMIKECloud (Grouped)
  • MIKECloud, just need basic upload/download by full pathMIKECloud (Flat)

Capabilities at a glance

Capability File MCLite MIKECloud (Grouped) MIKECloud (Flat)
Group listing (GetByGroup, GetFullNames)
GetAll() documents
Metadata search (values, token AND)
XML metadata search option
Overwrite on Add(id)
Get stream rewound No → seek to 0
Backing store Files DB Cloud Cloud

Need details? See the Documents MCLite / Documents MIKECloud provider guides.


IDs, paths & grouping (mental model)

  • File id = "group/sub/name.ext"<root>/group/sub/name.ext (+ <file>.metadata.json). Group = directories; fileType is the extension without dot.

  • MCLite id = "/Group/Sub/name.ext" (absolute path style). Folders live in folder tables; blobs are chunked (8KB). Filters are case-insensitive AND across values; optional XML metadata pass.

  • MIKECloud (Grouped & Flat) id = "group/sub/name.ext" → dataset at that path under the project tree. Note: provider returns fileType as .ext (with dot).


Registering providers (minimal wiring)

All controllers resolve services by connectionId from ServiceLocator.

1) File system

using DHI.Services;
using DHI.Services.Documents;

var root = Path.Combine(builder.Environment.ContentRootPath, "App_Data", "docs");
Directory.CreateDirectory(root);

ServiceLocator.Register(
    new GroupedDocumentService<string>(new FileDocumentRepository(root)),
    "files");

2) MCLite (PostgreSQL shown; SQLite/SQL Server similar)

using DHI.Services;
using DHI.Services.Documents;
using DHI.Services.Provider.MCLite;

var cs = "database=mc2014.2;host=localhost;port=5432;username=dss_admin;password=***;workspace=workspace1;dbflavour=PostgreSQL";

ServiceLocator.Register(
    new GroupedDocumentService<string>(new DocumentRepository(cs)),
    "mclite");

SQLite: "database=[AppData]MCSQLiteTest.sqlite;dbflavour=SQLite". If you use [AppData], set once at startup:

AppDomain.CurrentDomain.SetData("DataDirectory",
  Path.Combine(builder.Environment.ContentRootPath, "App_Data"));

3) MIKECloud (grouped)

using DHI.Services;
using DHI.Services.Documents;
using DHI.Services.Provider.MIKECloud;

var conn = "apiKey=<APIKEY>;projectId=<PROJECT_GUID>;environment=Prod";

ServiceLocator.Register(
    new GroupedDocumentService<string>(new GroupedDocumentRepository(conn)),
    "mikecloud");

4) MIKECloud (flat)

ServiceLocator.Register(
    new DocumentService<string>(new DHI.Services.Provider.MIKECloud.DocumentRepository(conn)),
    "mikecloud-flat");

Optional: configure via connections.json

If you prefer declarative wiring, create entries and materialize them at startup with DocumentServiceConnection / GroupedDocumentServiceConnection (they resolve [AppData] / [env:VAR]):

[
  {
    "type": "DHI.Services.Documents.WebApi.GroupedDocumentServiceConnection, DHI.Services.Documents.WebApi",
    "id": "files",
    "name": "Local Files",
    "repositoryType": "DHI.Services.Documents.FileDocumentRepository, DHI.Services.Documents",
    "connectionString": "[AppData]docs"
  },
  {
    "type": "DHI.Services.Documents.WebApi.GroupedDocumentServiceConnection, DHI.Services.Documents.WebApi",
    "id": "mclite",
    "name": "MCLite (PostgreSQL)",
    "repositoryType": "DHI.Services.Provider.MCLite.DocumentRepository, DHI.Services.MCLite",
    "connectionString": "database=mc2014.2;host=localhost;port=5432;username=dss_admin;password=***;workspace=workspace1;dbflavour=PostgreSQL"
  },
  {
    "type": "DHI.Services.Documents.WebApi.DocumentServiceConnection, DHI.Services.Documents.WebApi",
    "id": "mikecloud-flat",
    "name": "MIKECloud (Flat)",
    "repositoryType": "DHI.Services.Provider.MIKECloud.DocumentRepository, DHI.Services.MIKECloud",
    "connectionString": "apiKey=[env:MIKECLOUD_APIKEY];projectId=aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee;environment=Prod"
  }
]

Using it over HTTP

Once registered, each {connectionId} is available under:

/api/documents/{connectionId}/...

See Documents Web API guide for the full matrix. Remember ID encoding in URLs: /| and |||.


Validators (cross-cutting)

Upload validators attach to the service you registered and run before storage:

public sealed class PngValidator : BaseValidator
{
    public PngValidator() : base(@"\.png$") {}
    public override (bool validated, string message) Validate(Stream s) { /* … */ }
}

Services.Get<DocumentService<string>>("files").Validators.Add(new PngValidator());

(Details in Documents Core → Validators.)


Pitfalls & tips

  • MIKECloud content type: provider returns fileType with a dot (e.g., .pdf). The Web API’s switch expects without dot; unknowns fall back to application/octet-stream. Either trim in the provider or extend the switch to accept both.
  • MIKECloud (Flat) stream: call Seek(0, SeekOrigin.Begin) before reading.
  • SQLite pathing (MCLite): if using [AppData], set DataDirectory (see §5.2).
  • Metadata search semantics: tokenized, AND across tokens, case-insensitive values-only. XML search is MCLite-only and runs as a second pass when enabled.
  • Group tree options (MCLite): suffix ;nonrecursive / ;groupsonly (or both) in group arguments for direct-children/folders-only listings.
  • Large files (MCLite): blobs are 8KB blocks; ensure indexes on (id, block_no) for big datasets.
  • Overwrite behavior: all providers replace existing content on Add(id).