Save rich text editor content with a form post in ASP.NET Core

The simplest way to save an editor's content is an ordinary form. In ASP.NET Core you bind it to a property, like any other input, and there is no JavaScript to write.
The page model
using RichTextBox.ModelBinding;
public class EditArticleModel : PageModel
{
private readonly AppDbContext _db;
public EditArticleModel(AppDbContext db) => _db = db;
[BindProperty]
[RichTextHtml]
public string? Body { get; set; }
public async Task<IActionResult> OnPostAsync(int id)
{
if (!ModelState.IsValid) return Page();
var article = await _db.Articles.FindAsync(id);
if (article is null) return NotFound();
article.Body = Body ?? "";
await _db.SaveChangesAsync();
return RedirectToPage(new { id });
}
}
The form
<form method="post">
<richtextbox asp-for="Body" toolbar="default" height="400px"></richtextbox>
<button type="submit">Save</button>
</form>
The editor keeps its HTML in a form field, so the submit button and normal binding work as they do for a text box. Razor Pages' antiforgery token is added to the form as usual.
Why each part is there
[RichTextHtml]cleans the HTML during binding, so scripts never reach your database.- Redirecting after a save means that pressing Reload does not post the form twice.
- Binding a
stringis all the editor needs. The column should be large, such asnvarchar(max).
Without asp-for
If you do not have a model property, give the editor a name, and read it from the form yourself. That is the raw value, so clean it before you trust it:
<richtextbox name="Body" toolbar="default" height="300px"></richtextbox> // in the handler var html = Request.Form["Body"].ToString();
Loading existing content
With asp-for, the property's value is what the editor shows. Set it in OnGet:
public async Task<IActionResult> OnGetAsync(int id)
{
var article = await _db.Articles.FindAsync(id);
if (article is null) return NotFound();
Body = article.Body;
return Page();
}
In ASP.NET Core MVC it is the same idea: asp-for on your view model's property, with [RichTextHtml] on that property.