Create folders for images in an ASP.NET Core editor gallery

Once a site has a few hundred pictures, one long list stops being useful. People want folders such as "Products" or "2026 events". The gallery in RichTextBox has a New folder button that creates a real folder on the server.
What you need
Nothing beyond the gallery itself. app.MapRichTextBoxUploads() maps the endpoint, and a gallery opened in a folder uploads into that folder. Here is an editor with the gallery button:
<richtextbox name="Body"
toolbar="{bold,italic}|{insertgallery}|{undo,redo}"
height="400px"></richtextbox>
What the server checks
The folder name comes from the browser, so it is not trusted. The endpoint normalizes the folder path and the name, and the store resolves the result inside the upload root. A name such as ../../web.config cannot walk out of it: a path that leaves the root is refused.
Reading the same folders from your own code
The gallery's list comes from IRichTextBoxUploadBrowser, and you can inject the store and use it yourself, for example on an admin page:
public class MediaModel : PageModel
{
private readonly IRichTextBoxUploadStore _store;
private readonly IOptions<RichTextBoxOptions> _options;
public MediaModel(IRichTextBoxUploadStore store, IOptions<RichTextBoxOptions> options)
{
_store = store;
_options = options;
}
public UploadFolderListing? Listing { get; private set; }
public async Task OnGetAsync(string? folder)
{
if (_store is IRichTextBoxUploadBrowser browser)
Listing = await browser.ListAsync(folder ?? "", _options.Value);
}
}
Cloud storage has no real folders
S3 and Azure Blob only have key prefixes. A store for them decides what "create folder" means, often by writing a zero-byte marker so that an empty folder shows up in the list. The upload providers page has working samples.
Who may create folders
Creating a folder goes through the same endpoint group as uploading, so your authorization policy covers it too. RichTextBox has no separate switch for folders alone. If you need members who upload but cannot create folders, your own store can return false from CreateFolderAsync for them.