Téléverser des images depuis un éditeur de texte enrichi avec Razor Pages

Dans une application Razor Pages, deux envois distincts entourent l’éditeur. Chaque image est envoyée dès son insertion, vers un point de terminaison qui renvoie son URL. Plus tard, le formulaire de la page envoie le HTML terminé, qui contient ces URL, à OnPost. Cette page présente les deux et explique pourquoi ils restent séparés : le formulaire conserve son jeton antifalsification, et le HTML reste assez petit pour les limites de formulaire de Razor Pages.
Le formulaire
<form method="post" id="post">
<input type="hidden" asp-for="Html" />
<div id="editor"></div>
<p><button type="submit">Save</button> @Model.Message</p>
</form>
<script>
var editor = new RichTextEditor("#editor", {
toolbar: "full",
galleryEndpoint: "/rte/gallery",
maxUploadFileSize: 4000000 // same limit as the server, checked before the upload starts
});
var html = document.getElementById("Html");
editor.setHTMLCode(html.value);
document.getElementById("post").addEventListener("submit", function () {
html.value = editor.getHTMLCode();
});
</script><input type="hidden" asp-for="Html" />transporte le HTML. Le tag helper<form method="post">ajoute de lui-même le champ masqué__RequestVerificationToken.- L’éditeur démarre avec la valeur du champ masqué : après un envoi, la page affiche donc de nouveau le contenu enregistré.
- Le gestionnaire de soumission copie
editor.getHTMLCode()dans le champ juste avant l’envoi du formulaire.
Le modèle de page
// Razor Pages validates the antiforgery token on this POST by default; the <form> tag helper
// in Index.cshtml adds the hidden __RequestVerificationToken field. Save Html to your database here.
public void OnPost() => Message = $"Saved {Html?.Length ?? 0} characters of HTML.";[BindProperty] sur Html lie le champ lors du POST. Razor Pages valide le jeton antifalsification avant l’exécution de OnPost ; un envoi sans jeton a reçu un 400. Nettoyez le HTML sur le serveur avant de le stocker ou de l’afficher à d’autres utilisateurs : ce qu’envoie l’éditeur reste une entrée provenant du navigateur.
Pourquoi les images sont envoyées d’abord
Sans gestionnaire d’envoi, l’éditeur intègre une image collée dans le HTML sous forme d’URL data: en base64, c’est-à-dire un long texte. Une valeur de formulaire Razor Pages est limitée par FormOptions.ValueLengthLimit, 4,194,304 caractères par défaut. Avec un jeton valide, un envoi de formulaire de 100,000 caractères a été enregistré, et un envoi de 4,300,000 caractères a reçu un 400 avant l’exécution de OnPost. Avec la route d’envoi, le HTML ne contient qu’une courte URL par image. Après l’insertion d’une image envoyée dans un éditeur vide et un clic sur Save, la page a indiqué « Saved 108 characters of HTML. ».
La route d’envoi
rte-files.js, chargé sur la page, envoie chaque image vers /rte/upload : glisser-déposer, collage, boîte de dialogue Insert Image et bouton Upload de la galerie. La route est un point de terminaison Minimal API déclaré dans Program.cs avec app.MapRteFiles() :
rte.MapPost("/upload", async (HttpContext http, IFormFile? file, [FromForm] string? folder) =>
Json(await RteFiles.Save(http, file, folder)))
.DisableAntiforgery()
// Kestrel accepts 30,000,000-byte bodies by default; this route needs ~4 MB.
.WithMetadata(new RequestSizeLimitAttribute(RteFiles.MaxRequestBytes))
.WithFormOptions(multipartBodyLengthLimit: RteFiles.MaxRequestBytes);Ce ne peut pas être un gestionnaire de page, car les gestionnaires s’adressent par /?handler=Upload et chaque gestionnaire POST exige le jeton antifalsification, que la XHR de l’éditeur ne peut pas envoyer. Ajouter une galerie d’images à un éditeur de texte enrichi avec Razor Pages explique ce choix. Les deux limites maintiennent la requête sous 4,065,536 octets ; sinon, Kestrel accepterait 30,000,000. RteFiles.Save vérifie ensuite l’origine, le dossier, la taille, l’extension et les premiers octets, et stocke le fichier sous un nouveau nom. Ces vérifications sont les mêmes que dans le guide sur l’envoi avec ASP.NET Core.

Tester
Lancez le projet d’exemple de ce guide avec dotnet run et ouvrez http://localhost:5303. Insérez une image depuis la galerie, envoyez-en une avec son bouton Upload si vous le souhaitez, puis cliquez sur Save : le message indique la longueur du HTML, et l’image est toujours là après le rechargement de la page. Depuis un shell :
curl -F "file=@photo.jpg" http://localhost:5303/rte/upload
{"url":"/uploads/photo-4cdaeb3e.jpg"}
curl -s -o /dev/null -w "%{http_code}\n" -d "Html=x" http://localhost:5303/
400L’envoi fonctionne sans jeton. L’envoi de formulaire brut est refusé, car il n’en a pas.
Le même guide pour d’autres plateformes
JavaScript · Next.js · PHP · ASP.NET Core · Blazor · MVC 5 · Web Forms