
Construire un visualiseur de gestion de documents sécurisé en .NET avec Doconut
Mise en œuvre de la gestion de documents avec Doconut
Un flux de gestion de documents dans un portail .NET nécessite généralement trois éléments :
- Un moyen de charger des PDF, des fichiers Office, des dessins CAD ou des images sans écrire un visualiseur à partir de zéro.
- Un jeton sécurisé qui lie le document chargé à la session du navigateur en cours.
- Une étape de nettoyage qui libère la mémoire dès que l'utilisateur a terminé.
Doconut fournit les trois via un service Viewer unique, une session IMemoryCache légère et des appels explicites CloseDocument.
1. Enregistrer le visualiseur dans le conteneur DI
Lors du démarrage de l'application, ajoutez les services Doconut au conteneur DI en appelant la méthode d'enregistrement Doconut décrite dans la documentation officielle. Cette étape enregistre le visualiseur, la gestion de licence et le cache en mémoire qui contiendra les sessions de documents.
L'enregistrement valide la licence au démarrage, ainsi toute licence manquante ou invalide échoue rapidement et vous connaissez le problème avant que la première requête n'atteigne le serveur.
2. Insérer le middleware qui fournit les images de page, les miniatures et les données d'annotation
Configurez le middleware Doconut dans le pipeline de requêtes afin que toute requête contenant une chaîne de requête ?token= soit gérée par Doconut. Le middleware applique le marqueur de sécurité par défaut (secure-{token}) lorsque UnsafeMode est false (la valeur par défaut) et fournit les images de page, les miniatures et les données d'annotation.
Placer le middleware sur une branche dédiée laisse le reste de votre pipeline intact et permet une mise à l'échelle horizontale sans sessions persistantes.
3. Ouvrir un document et obtenir le jeton de session opaque
Créez un point de terminaison unique qui reçoit un chemin de fichier (ou un flux) et renvoie le jeton. Le jeton est le seul identifiant que le widget client voit jamais.
app.MapPost("/api/open", async (Viewer viewer) =>
{
// Le jeton est opaque — remettez‑le au widget, ne le consignez ni ne le persistez.
string token = await viewer.OpenDocumentAsync("wwwroot/files/Contract.pdf");
return Results.Ok(new { token });
});
Ce qui se passe à l'intérieur de OpenDocumentAsync
- Portail de licence – une licence invalide lance immédiatement
LicenseException. - Création de session – Doconut sélectionne le visualiseur de format approprié (PDF, Word, DWG, …) et stocke le moteur dans
IMemoryCachesous un jeton GUID. - Enregistrement de sécurité – avec
UnsafeMode = falsele jeton est lié à la session ASP.NET de l'appelant via un marqueursecure-{token}. Seule cette session de navigateur peut demander des pages. - Retour du jeton – le client reçoit le jeton et l'utilise pour chaque requête ultérieure (
/DocImage.axd?token=…).
L'expiration glissante par défaut est de 60 minutes (configurable via DocOptions.TimeOut). Chaque requête de page réinitialise le compteur, de sorte que les sessions inactives disparaissent automatiquement.
4. Rendre le document côté client
Depuis le navigateur, vous appelez le point de terminaison, récupérez le jeton et le transmettez au widget Doconut :
fetch('/api/open', { method: 'POST' })
.then(r => r.json())
.then(d => {
const token = d.token;
objViewer.View(token); // Widget JavaScript fourni par Doconut
});
Le widget émet en interne des requêtes de page, de miniature, de recherche et d'annotation qui incluent toutes le même token. Parce que le jeton est lié à la session côté serveur, un utilisateur malveillant ne peut pas détourner le document d'un autre utilisateur.
5. Fermer le document dès que l'utilisateur quitte le visualiseur
Pour les gros PDF ou fichiers CAD, vous devez libérer le moteur de rendu immédiatement. Appelez CloseDocument depuis un point de terminaison côté serveur ou depuis l'événement « unload » du widget.
// Point de terminaison côté serveur
app.MapPost("/api/close", (Viewer viewer, string token) =>
{
viewer.CloseDocument(token);
return Results.Ok();
});
// Appel direct depuis le widget (si vous exposez le jeton au backend)
viewer.CloseDocument(token);
CloseDocument supprime la session du cache, libère le moteur de document sous‑jacent, supprime le marqueur secure-{token}, et révoque l'autorisation d'accès. L'expiration glissante finirait par faire la même chose, mais une fermeture explicite garantit que la mémoire est récupérée dès que l'utilisateur a terminé.
6. Optionnel : Convertir un document sur le serveur
Si votre flux de travail nécessite une exportation PDF d'un fichier Word téléchargé, activez le plugin Converter dans la configuration Doconut (voir la documentation). Après l'enregistrement du plugin, vous pouvez injecter DocumentConverter et appeler sa méthode ConvertAsync. La conversion s'exécute sur le serveur, vous n'avez donc jamais besoin d'Office installé sur le serveur web.
7. Considérations d'évolutivité pour la gestion de documents de niveau entreprise
- Front‑ends sans état – Le widget visualiseur ne détient jamais les données du document ; tout le traitement lourd reste sur le serveur.
- Cache distribué – Remplacez le cache en mémoire par défaut par un fournisseur distribué (Redis, NCache) si vous exécutez plusieurs nœuds de ferme web. Le mappage jeton‑session fonctionne tel quel parce que le middleware lit depuis le
IMemoryCacheconfiguré. - Jobs en arrière‑plan – Vous pouvez pré‑ouvrir des documents dans un worker en arrière‑plan, mettre le jeton en cache et le transmettre à l'UI plus tard. N'oubliez pas que chaque jeton est à usage unique par session ; la réutilisation nécessite un nouvel appel
OpenDocumentAsync.
Ces modèles vous permettent de créer une plateforme de gestion de documents qui s'étend d'un portail intranet à serveur unique à un service cloud multi‑région sans réécrire la logique du visualiseur.
8. Checklist rapide pour une implémentation prête pour la production
| Étape | Action |
|---|---|
| 1 | Enregistrez les services Doconut dans Program.cs (valider la licence). |
| 2 | Ajoutez le middleware Doconut sur une branche dédiée. |
| 3 | Exposez un point de terminaison /api/open qui appelle OpenDocumentAsync. |
| 4 | Transmettez le jeton retourné à objViewer.View(token) dans le client. |
| 5 | Appelez CloseDocument(token) lorsque le visualiseur est masqué ou que la page se décharge. |
| 6 | (Optionnel) Activez ConverterPlugin si vous avez besoin d'une conversion côté serveur. |
| 7 | (Optionnel) Remplacez IMemoryCache par un cache distribué pour l'évolutivité horizontale. |
Suivez la liste, et vous disposez d'un flux complet, sécurisé et haute performance de gestion de documents construit sur le visualiseur .NET natif de Doconut.