Skip to main content

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

The editor with a formatted document

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

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.

Read next