Gestor de archivos ASP.NET MVC gratuito con visor de PDF integrado
← Back to Blog••6 min read

Gestor de archivos ASP.NET MVC gratuito con visor de PDF integrado

Construye un gestor de archivos ASP.NET MVC gratuito que muestra PDFs

Quieres una página que liste los archivos almacenados en el servidor, permita al usuario descargarlos o eliminarlos, y abra cualquier PDF en el navegador sin salir del sitio. La siguiente guía te muestra cómo hacer exactamente eso con ASP.NET MVC puro, la caché de sesión incorporada y el visor universal de documentos de Doconut.


1. Genera una aplicación MVC mínima

Crea un nuevo proyecto MVC en Visual Studio (cualquier edición, incluida la edición Community gratuita).

Agrega un FileController que alojará las acciones del gestor de archivos:

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();

        // The viewer token is created here (see section 2)
        var token = await _viewer.OpenDocumentAsync(
            path,
            new Doconut.PdfConfig { AllowSearch = true },
            new DocOptions(),
            CancellationToken.None);

        ViewBag.Token = token;
        ViewBag.BasePath = "doconut";          // matches the middleware branch
        ViewBag.ResPath = "doconut-res/images";// embedded resources
        return View();
    }

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

El controlador hace tres cosas:

  1. Index – lee la carpeta App_Data/Docs y pasa los nombres de archivo a una vista.
  2. Download / Delete – acciones MVC estándar que usan el asistente PhysicalFile incorporado.
  3. ViewPdf – abre el PDF seleccionado con Doconut, recibe un token de seguridad y lo pasa a una vista Razor.

2. Configura el estado de sesión y los servicios de Doconut

El visor de Doconut depende del estado de sesión de ASP.NET para proteger el token que identifica un documento. Agrega los servicios requeridos en Program.cs (o Startup.cs para proyectos .NET 6):

var builder = WebApplication.CreateBuilder(args);

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

// Session cache – required for token validation
builder.Services.AddDistributedMemoryCache();
builder.Services.AddSession();

// Doconut registration – point to your license file
builder.Services.AddDoconut(options =>
{
    options.LicensePath = Path.Combine(AppContext.BaseDirectory, "wwwroot", "Doconut.Viewer.lic");
    options.MiddlewarePath = "/doconut";
    options.ResourcesPath = "/doconut-res";
    options.UnsafeMode = false; // keep the default security
});

var app = builder.Build();

// Session must run before the viewer middleware
app.UseSession();

// The Doconut middleware must be mapped to the path configured above.
// See Doconut documentation for the exact mapping call (e.g., app.Map("/doconut", …)).

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

app.Run();

Puntos clave:

  • AddDistributedMemoryCache proporciona el almacén en memoria que necesita AddSession.
  • UseSession() debe aparecer antes del middleware de Doconut; de lo contrario verás el error en tiempo de ejecución “Session middleware not configured.”
  • MiddlewarePath y ResourcesPath son cadenas de coordinación – la rama real del middleware debe coincidir con la ruta que configures.

3. Crear la vista del Administrador de Archivos

Cree Views/File/Index.cshtml. Lista los archivos y proporciona acciones para descargar, eliminar y ver 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>

Cuando el usuario hace clic en View PDF, la acción ViewPdf crea un token y devuelve una segunda vista que aloja el widget del visor.


4. Renderizar el visor Doconut

Cree Views/File/ViewPdf.cshtml. La página solo necesita un elemento contenedor; el widget JavaScript se carga desde los recursos incrustados.

@{
    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>

El widget lee el AccessToken que proporcionó, contacta el endpoint /doconut/DocImage.axd y transmite cada página como una imagen. Debido a que el token está vinculado a la sesión actual de ASP.NET, un usuario no puede copiar la URL y ver el documento desde otro navegador sin la misma cookie de sesión.


5. Manejo de la expiración del token y seguridad

El tiempo de expiración predeterminado del token de Doconut es de 60 minutos (configurable a través de DocOptions.TimeOut). Si el visor recibe “Document session not found” o “You Are Not Authorized To View This Page”, la sesión ha expirado o la solicitud proviene de un contexto de navegador diferente.

Remedios típicos:

  • Actualizar la página – el controlador generará un token nuevo.
  • Aumentar el tiempo de espera – pase un DocOptions personalizado al abrir el documento:
var options = new DocOptions { TimeOut = TimeSpan.FromHours(2) };
var token = await _viewer.OpenDocumentAsync(
    path,
    new Doconut.PdfConfig { AllowSearch = true },
    options,
    CancellationToken.None);
  • Configuraciones de origen cruzado – asegúrese de que el atributo SameSite en la cookie de sesión sea compatible con su dominio front‑end. El valor predeterminado Lax funciona para la mayoría de los portales de mismo origen.

6. Extender el Administrador (Opcional)

El administrador de archivos central ya funciona, pero puede que desee agregar:

  • Upload – un formulario simple que envía un IFormFile y lo guarda en _root.
  • Folder navigation – modifique la acción Index para aceptar una ruta relativa y protegerla contra la traversía de directorios (Path.GetFullPath + verificación StartsWith(_root)).
  • Search – filtre files por nombre antes de pasarlos a la vista.

Todas estas extensiones permanecen dentro del mismo patrón MVC y continúan beneficiándose del mismo visor Doconut protegido por sesión.


7. Lo que has logrado

  • Un administrador de archivos ASP.NET MVC gratuito – sin bibliotecas UI de terceros, sin tarifas de licencia.
  • Renderizado de PDF en el navegador a través del visor universal de Doconut, evitando la necesidad de instalaciones de Office o Adobe en el cliente.
  • Acceso seguro basado en tokens que aprovecha el estado de sesión de ASP.NET, evitando el uso compartido arbitrario de URLs.
  • Una base de código única que funciona para .NET 6 y .NET 8 y puede portarse a Razor Pages o APIs mínimas con solo cambiar las llamadas de registro (AddDoconut, UseSession).

Despliegue la aplicación en IIS, Azure App Service o Docker – la misma configuración de Program.cs funciona en todas partes porque Doconut se ejecuta en .NET 6+ y no requiere componentes nativos de Office.

#ASP.NET MVC#File Manager#PDF Viewer#.NET#Doconut#Gestor de archivos#Visor de PDF