
Darmowy menedżer plików ASP.NET MVC z wbudowaną przeglądarką PDF
Zbuduj darmowy menedżer plików ASP.NET MVC, który wyświetla PDF-y
Chcesz mieć stronę, która wyświetla listę plików przechowywanych na serwerze, umożliwia ich pobieranie lub usuwanie oraz otwiera każdy PDF w przeglądarce bez opuszczania witryny. Poniższy przewodnik pokazuje, jak zrobić to dokładnie przy użyciu czystego ASP.NET MVC, wbudowanej pamięci sesji i uniwersalnego przeglądarki dokumentów Doconut.
1. Utwórz minimalną aplikację MVC
Utwórz nowy projekt MVC w Visual Studio (dowolna edycja, w tym darmowa edycja Community).
Dodaj FileController, który będzie obsługiwał akcje menedżera plików:
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;
}
Kontroler wykonuje trzy czynności:
- Index – odczytuje folder
App_Data/Docsi przekazuje nazwy plików do widoku. - Download / Delete – standardowe akcje MVC, które używają wbudowanego pomocnika
PhysicalFile. - ViewPdf – otwiera wybrany PDF przy użyciu Doconut, otrzymuje token bezpieczeństwa i przekazuje go do widoku Razor.
2. Skonfiguruj stan sesji i usługi Doconut
Przeglądarka Doconut opiera się na stanie sesji ASP.NET, aby chronić token identyfikujący dokument. Dodaj wymagane usługi w Program.cs (lub Startup.cs dla projektów .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();
Kluczowe punkty:
AddDistributedMemoryCachezapewnia pamięć w‑ramce potrzebnąAddSession.UseSession()musi pojawić się przed middleware Doconut; w przeciwnym razie pojawi się błąd czasu wykonania „Session middleware not configured.”MiddlewarePathiResourcesPathsą łańcuchami koordynacyjnymi – rzeczywisty branch middleware musi odpowiadać skonfigurowanej ścieżce.
3. Utwórz widok menedżera plików
Utwórz Views/File/Index.cshtml. Wyświetla listę plików i zapewnia akcje pobierania, usuwania oraz podglądu 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>
Gdy użytkownik kliknie View PDF, akcja ViewPdf tworzy token i zwraca drugi widok, który hostuje widget przeglądarki.
4. Renderuj przeglądarkę Doconut
Utwórz Views/File/ViewPdf.cshtml. Strona wymaga jedynie elementu kontenera; widget JavaScript jest ładowany z zasobów osadzonych.
@{
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>
Widget odczytuje podany przez Ciebie AccessToken, kontaktuje się z endpointem /doconut/DocImage.axd i przesyła każdą stronę jako obraz. Ponieważ token jest powiązany z bieżącą sesją ASP.NET, użytkownik nie może skopiować adresu URL i wyświetlić dokumentu w innej przeglądarce bez tego samego ciasteczka sesji.
5. Obsługa wygaśnięcia tokenu i bezpieczeństwo
Domyślny limit czasu tokenu w Doconut wynosi 60 minut (można go skonfigurować poprzez DocOptions.TimeOut). Jeśli przeglądarka otrzyma „Document session not found” lub „You Are Not Authorized To View This Page”, sesja wygasła lub żądanie pochodzi z innego kontekstu przeglądarki.
Typowe rozwiązania:
- Odśwież stronę – kontroler wygeneruje nowy token.
- Zwiększ limit czasu – przekaż własny
DocOptionsprzy otwieraniu dokumentu:
var options = new DocOptions { TimeOut = TimeSpan.FromHours(2) };
var token = await _viewer.OpenDocumentAsync(
path,
new Doconut.PdfConfig { AllowSearch = true },
options,
CancellationToken.None);
- Ustawienia cross‑origin – upewnij się, że atrybut
SameSitew ciasteczku sesji jest zgodny z domeną front‑endu. DomyślneLaxdziała w większości portali o tej samej pochodzeniu.
6. Rozszerzanie menedżera (opcjonalnie)
Podstawowy menedżer plików jest już funkcjonalny, ale możesz chcieć dodać:
- Upload – prosty formularz, który wysyła
IFormFilei zapisuje go w_root. - Nawigacja po folderach – zmodyfikuj akcję
Index, aby przyjmowała ścieżkę względną i chroniła ją przed traversą katalogów (Path.GetFullPath+ sprawdzenieStartsWith(_root)). - Search – przefiltruj
filespo nazwie przed przekazaniem ich do widoku.
Wszystkie te rozszerzenia pozostają w ramach tego samego wzorca MVC i nadal korzystają z tego samego, chronionego sesją, widoku Doconut.
7. Co udało Ci się osiągnąć
- Bezpłatny menedżer plików ASP.NET MVC – bez bibliotek UI innych firm, bez opłat licencyjnych.
- Renderowanie PDF w przeglądarce za pomocą uniwersalnego widoku Doconut, eliminując potrzebę instalacji Office lub Adobe po stronie klienta.
- Bezpieczny dostęp oparty na tokenie wykorzystujący stan sesji ASP.NET, zapobiegający dowolnemu udostępnianiu adresu URL.
- Jedna baza kodu, działająca na .NET 6 i .NET 8 oraz możliwa do przeniesienia na Razor Pages lub minimalne API, przy zmianie jedynie wywołań rejestracji (
AddDoconut,UseSession).
Wdroż aplikację na IIS, Azure App Service lub Docker – ta sama konfiguracja w Program.cs działa wszędzie, ponieważ Doconut działa na .NET 6+ i nie wymaga żadnych natywnych komponentów Office.