
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:
- Index – lee la carpeta
App_Data/Docsy pasa los nombres de archivo a una vista. - Download / Delete – acciones MVC estándar que usan el asistente
PhysicalFileincorporado. - 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:
AddDistributedMemoryCacheproporciona el almacén en memoria que necesitaAddSession.UseSession()debe aparecer antes del middleware de Doconut; de lo contrario verás el error en tiempo de ejecución “Session middleware not configured.”MiddlewarePathyResourcesPathson 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
DocOptionspersonalizado 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
SameSiteen la cookie de sesión sea compatible con su dominio front‑end. El valor predeterminadoLaxfunciona 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
IFormFiley lo guarda en_root. - Folder navigation – modifique la acción
Indexpara aceptar una ruta relativa y protegerla contra la traversía de directorios (Path.GetFullPath+ verificaciónStartsWith(_root)). - Search – filtre
filespor 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.