Gestore di file ASP.NET MVC gratuito con visualizzatore PDF integrato
← Back to Blog••6 min read

Gestore di file ASP.NET MVC gratuito con visualizzatore PDF integrato

Crea un gestore di file ASP.NET MVC gratuito che mostra PDF

Vuoi una pagina che elenchi i file memorizzati sul server, permetta all'utente di scaricarli o eliminarli, e apra qualsiasi PDF nel browser senza lasciare il sito. La guida seguente ti mostra come fare esattamente questo con ASP.NET MVC puro, la cache di sessione integrata e il visualizzatore universale di documenti di Doconut.


1. Genera un'applicazione MVC minima

Crea un nuovo progetto MVC in Visual Studio (qualsiasi edizione, inclusa la versione Community gratuita).

Aggiungi un FileController che ospiterà le azioni del gestore di file:

public class FileController : Controller
{
    private readonly string _root = Path.Combine(Directory.GetCurrentDirectory(), "App_Data", "Docs");

    public IActionResult Index()
    {
        var files = Directory.GetFiles(_root).Select(Path.GetFileName).ToList();
        return View(files);
    }

    public IActionResult Download(string name)
    {
        var path = Path.Combine(_root, name);
        if (!System.IO.File.Exists(path)) return NotFound();
        var mime = "application/octet-stream";
        return PhysicalFile(path, mime, name);
    }

    public IActionResult Delete(string name)
    {
        var path = Path.Combine(_root, name);
        if (System.IO.File.Exists(path)) System.IO.File.Delete(path);
        return RedirectToAction(nameof(Index));
    }

    public async Task<IActionResult> ViewPdf(string name)
    {
        var path = Path.Combine(_root, name);
        if (!System.IO.File.Exists(path)) return NotFound();

        // Il token del visualizzatore viene creato qui (vedi sezione 2)
        var token = await _viewer.OpenDocumentAsync(
            path,
            new Doconut.PdfConfig { AllowSearch = true },
            new DocOptions(),
            CancellationToken.None);

        ViewBag.Token = token;
        ViewBag.BasePath = "doconut";          // corrisponde al ramo del middleware
        ViewBag.ResPath = "doconut-res/images";// risorse incorporate
        return View();
    }

    private readonly Doconut.Viewer _viewer;
    public FileController(Doconut.Viewer viewer) => _viewer = viewer;
}

Il controller fa tre cose:

  1. Index – legge la cartella App_Data/Docs e passa i nomi dei file a una vista.
  2. Download / Delete – azioni MVC standard che utilizzano l'helper integrato PhysicalFile.
  3. ViewPdf – apre il PDF selezionato con Doconut, riceve un token di sicurezza e lo passa a una vista Razor.

2. Configura lo stato della sessione e i servizi Doconut

Il visualizzatore di Doconut si basa sullo stato della sessione di ASP.NET per proteggere il token che identifica un documento. Aggiungi i servizi richiesti in Program.cs (o Startup.cs per progetti .NET 6):

var builder = WebApplication.CreateBuilder(args);

// Servizi MVC
builder.Services.AddControllersWithViews();

// Cache della sessione – necessaria per la convalida del token
builder.Services.AddDistributedMemoryCache();
builder.Services.AddSession();

// Registrazione Doconut – indica il percorso del file di licenza
builder.Services.AddDoconut(options =>
{
    options.LicensePath = Path.Combine(AppContext.BaseDirectory, "wwwroot", "Doconut.Viewer.lic");
    options.MiddlewarePath = "/doconut";
    options.ResourcesPath = "/doconut-res";
    options.UnsafeMode = false; // mantieni la sicurezza predefinita
});

var app = builder.Build();

// La sessione deve essere avviata prima del middleware del visualizzatore
app.UseSession();

// Il middleware Doconut deve essere mappato al percorso configurato sopra.
// Consulta la documentazione Doconut per la chiamata di mapping esatta (ad es., app.Map("/doconut", …)).

app.UseRouting();
app.UseEndpoints(endpoints => endpoints.MapDefaultControllerRoute());

app.Run();

Punti chiave:

  • AddDistributedMemoryCache fornisce lo store in‑memoria necessario a AddSession.
  • UseSession() deve apparire prima del middleware Doconut; altrimenti vedrai l'errore di runtime “Session middleware not configured.”
  • MiddlewarePath e ResourcesPath sono stringhe di coordinamento – il ramo middleware effettivo deve corrispondere al percorso configurato.

3. Crea la vista del File‑Manager

Crea Views/File/Index.cshtml. Elenca i file e fornisce azioni per il download, l'eliminazione e la visualizzazione PDF.

@model List<string>
<h2>Document Library</h2>
<table>
    <thead><tr><th>Name</th><th>Actions</th></tr></thead>
    <tbody>
@foreach (var f in Model)
{
    <tr>
        <td>@f</td>
        <td>
            <a asp-action="Download" asp-route-name="@f">Download</a> |
            <a asp-action="Delete"   asp-route-name="@f">Delete</a> |
            @if (Path.GetExtension(f).Equals(".pdf", StringComparison.OrdinalIgnoreCase))
            {
                <a asp-action="ViewPdf" asp-route-name="@f">View PDF</a>
            }
        </td>
    </tr>
}
    </tbody>
</table>

Quando l'utente fa clic su View PDF, l'azione ViewPdf crea un token e restituisce una seconda vista che ospita il widget del visualizzatore.


4. Renderizza il visualizzatore Doconut

Crea Views/File/ViewPdf.cshtml. La pagina ha bisogno solo di un elemento contenitore; il widget JavaScript viene caricato dalle risorse incorporate.

@{
    var token = ViewBag.Token as string;
    var basePath = ViewBag.BasePath as string;
    var resPath = ViewBag.ResPath as string;
}
<h2>PDF Preview</h2>
<div id="div_ctlDoc"></div>

<script src="@($"{basePath}/docViewer.js")"></script>
<link rel="stylesheet" href="@($"{basePath}/docViewer.css")" />

<script>
    $('#div_ctlDoc').docViewer({
        AccessToken: '@token',
        BasePath: '@basePath',
        ResPath: '@resPath',
        FitType: 'width',
        showThumbs: true,
        autoLoad: true,
        onError: function (msg) { console.error(msg); }
    });
</script>

Il widget legge l'AccessToken fornito, contatta il endpoint /doconut/DocImage.axd e trasmette ogni pagina come immagine. Poiché il token è legato alla sessione ASP.NET corrente, un utente non può copiare l'URL e visualizzare il documento da un altro browser senza lo stesso cookie di sessione.


5. Gestione della scadenza del token e sicurezza

Il timeout predefinito del token di Doconut è di 60 minuti (configurabile tramite DocOptions.TimeOut). Se il visualizzatore riceve “Document session not found” o “You Are Not Authorized To View This Page”, la sessione è scaduta oppure la richiesta proviene da un contesto di browser diverso.

Rimedi tipici:

  • Aggiorna la pagina – il controller genererà un nuovo token.
  • Aumenta il timeout – passa un DocOptions personalizzato quando apri il documento:
var options = new DocOptions { TimeOut = TimeSpan.FromHours(2) };
var token = await _viewer.OpenDocumentAsync(
    path,
    new Doconut.PdfConfig { AllowSearch = true },
    options,
    CancellationToken.None);
  • Configurazioni cross‑origin – assicurati che l'attributo SameSite sul cookie di sessione sia compatibile con il dominio del tuo front‑end. Il valore predefinito Lax funziona per la maggior parte dei portali same‑origin.

6. Estendere il manager (opzionale)

Il gestore di file di base è già funzionale, ma potresti voler aggiungere:

  • Upload – un semplice modulo che invia un IFormFile e lo salva in _root.
  • Navigazione delle cartelle – modifica l'azione Index per accettare un percorso relativo e proteggerlo da traversal di directory (Path.GetFullPath + controllo StartsWith(_root)).
  • Ricerca – filtra i files per nome prima di passarli alla vista.

Tutte queste estensioni rimangono all'interno dello stesso pattern MVC e continuano a beneficiare dello stesso visualizzatore Doconut protetto da sessione.


7. Cosa hai ottenuto

  • Un gestore di file ASP.NET MVC gratuito – nessuna libreria UI di terze parti, nessuna tassa di licenza.
  • Rendering PDF nel browser tramite il visualizzatore universale di Doconut, evitando la necessità di installazioni di Office o Adobe sul client.
  • Accesso sicuro basato su token che sfrutta lo stato della sessione ASP.NET, impedendo la condivisione arbitraria di URL.
  • Una singola base di codice che funziona per .NET 6 e .NET 8 e può essere portata a Razor Pages o API minime con solo le chiamate di registrazione (AddDoconut, UseSession) da modificare.

Distribuisci l'app su IIS, Azure App Service o Docker – la stessa configurazione Program.cs funziona ovunque perché Doconut gira su .NET 6+ e non richiede componenti Office nativi.

#ASP.NET MVC#File Manager#PDF Viewer#.NET#Doconut#Gestore di file#Visualizzatore PDF