Open Closed

ABP Suite: Issue with Default Image Upload Behavior in ABP Suite (Upload Triggered Before Create Action) #10546


User avatar
0
chrisalves created

Check the docs before asking a question: https://abp.io/docs/latest Check the samples to see the basic tasks: https://abp.io/docs/latest/samples The exact solution to your question may have been answered before, and please first use the search on the homepage.

Provide us with the following info: 🧐 Hint: If you are using the ABP Studio, you can see all the information about your solution from the configuration window, which opens when you right-click on the solution and click on the Solution Configuration button.

  • Template: app
  • Created ABP Studio Version: 1.0.2
  • Current ABP Studio Version: 1.4.1
  • Tiered: Yes
  • Multi-Tenancy: Yes
  • UI Framework: blazor-server
  • Theme: leptonx
  • Theme Style: system
  • Theme Menu Placement: side
  • Run Install Libs: Yes
  • Database Provider: ef
  • Database Management System: sqlserver
  • Separate Tenant Schema: Yes
  • Create Initial Migration: Yes
  • Run Db Migrator: Yes
  • Mobile Framework: maui
  • Public Website: Yes
  • Social Login: Yes
  • Include Tests: Yes
  • Kubernetes Configuration: No
  • Distributed Event Bus: rabbitmq
  • Use Local References: No
  • Optional Modules:
    • GDPR
    • FileManagement
    • TextTemplateManagement
    • LanguageManagement
    • AuditLogging
    • Chat
    • OpenIddictAdmin
  • Selected Languages: English, English (United Kingdom), 简体中文, EspaƱol, Ų§Ł„Ų¹Ų±ŲØŁŠŲ©, ą¤¹ą¤æą¤Øą„ą¤¦ą„€, PortuguĆŖs (Brasil), FranƧais, Русский, Deutsch (Deuthschland), TürkƧe, Italiano, ČeÅ”tina, Magyar, RomĆ¢nă (RomĆ¢nia), Svenska, Suomi, Slovenčina, ƍslenska, 繁體中文
  • Default Language: English
  • Create Command: abp new NewApp -t app --tiered --ui-framework blazor-server --mobile maui --database-provider ef --database-management-system sqlserver --theme leptonx --separate-tenant-schema --public-website --without-cms-kit --dont-run-bundling -chat -file-management
  • Exception message and full stack trace:
  • Steps to reproduce the issue:

I have a question regarding the default behavior of the ABP Suite templates, specifically related to file upload fields (as shown in the attached screenshot).

By default, when the user selects an image in the input field, the upload is triggered immediately on the frontend. The problem is that if the user cancels the operation like refreshing the page (F5) or closes/discards the form the uploaded file remains stored both in the file descriptor and in Blob Storage and there is no instruction on how to avoid it or cleanup procedure.

I would like to know what you recommend for handling this scenario, the ABP Architecture recomendation on how to handle this issue, as example below but not limited to them.

  • Is there a way to adjust or extend the ABP Suite templates so that the upload only occurs during the Create action (i.e., only after the user clicks the SAVE button)?
  • Is this issue mapped by ABP and there is a workaround solution until the fix to be implemented on a future release?
  • Alternatively, is there a recommended approach to automatically clean up previously uploaded files when the user cancels the form?

I understand that it is possible to implement a fully custom upload flow but I preffer to keep as much as possible the standard ABP solution/architecture. Before going down that path for customization, I would like to know whether ABP Suite provides any recommended extension points or best practices to modify this default behavior.

Thank you in advance for your guidance.


2 Answer(s)
  • User Avatar
    0
    AI-Bot created
    Support Team ABP Agent
    • In the ABP Suite-generated Blazor CRUD pages, the ā€œFileā€ property uses a select file → upload immediately UX. With BLOB Storage/File Management this means a FileDescriptor + blob content can be created before the main entity is saved. If the user closes the modal / refreshes, those uploaded blobs can remain orphaned unless you add a cleanup strategy.
    • There isn’t a built-in ABP Suite switch (template option) that changes this to ā€œupload only on Saveā€ for generated pages (no verified source available for a Suite extension point that flips this behavior).

    Recommended ABP-style approaches

    A) ā€œUpload on Saveā€ (recommended if you want zero orphan risk)

    Implement the create/edit form so it does not call the server on file selection. Instead:

    1. On file selection, keep the file in memory (or stream) on the Blazor side and only show a preview.
    2. When the user clicks Save, call your Application Service CreateAsync(...) and pass the file content as IRemoteStreamContent (or a byte[] if small), then inside the same application service method:
      • Create the entity
      • Save the blob
      • Store the blob/file id on the entity
      • Commit once (same unit of work)

    This matches ABP’s general ā€œdo it in the application service in a single use-caseā€ style and avoids a ā€œtemporary uploadā€ concept entirely.

    B) Keep immediate upload, but add an automatic cleanup (recommended if you want to keep Suite UX)

    If you keep the default immediate upload, use a ā€œtemporary uploadā€ + scheduled cleanup pattern:

    1. When the file is uploaded, mark it as temporary (e.g., store a flag/metadata, or put it under a ā€œtemp/ā€ naming convention, or store it in a dedicated container).
    2. When the user clicks Save and the entity is created, ā€œfinalizeā€ the file:
      • clear the temporary flag (or move/rename)
      • associate it with the created entity
    3. Run a background job (periodic worker) that deletes temporary files older than X minutes/hours (and their descriptors).

    ABP’s Blob Storing API supports deleting blobs, so the cleanup job can safely remove old temporary items.

    C) Compensating cleanup on Cancel (best-effort only)

    In the modal’s Cancel/Close handler (and on dispose/navigation), call an endpoint to delete the already-uploaded file descriptor/blob if it hasn’t been finalized. This reduces leftovers but won’t cover hard refresh/tab close/network loss—so you still typically want (B) as the safety net.


    Minimal cleanup code idea (server side)

    Use ABP Blob Storing’s container API to remove orphaned blobs when needed (e.g., in a background worker or explicit cancel endpoint):

    public class MyFileCleanupService : ITransientDependency
    {
        private readonly IBlobContainer<MyFileContainer> _container;
    
        public MyFileCleanupService(IBlobContainer<MyFileContainer> container)
        {
            _container = container;
        }
    
        public Task DeleteAsync(string blobName)
        {
            return _container.DeleteAsync(blobName);
        }
    }
    

    You’d combine this with whatever ā€œtemporaryā€ tracking you use (DB table/flag, naming convention, etc.) to find candidates to delete.


    References (verified)

    • https://docs.abp.io/en/abp/latest/Blob-Storing
    • https://abp.io/community/articles/d01cbe12
    • https://abp.io/community/articles/sr7t3w4p

    This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.

  • User Avatar
    0
    chrisalves created

    Hi ABP Folks,

    I“d like to get an architect guy guidance instead of bot answer to be as close as possible of the ABP solution evolution.

Boost Your Development
ABP Live Training
Packages
See Trainings
Mastering ABP Framework Book
The Official Guide
Mastering
ABP Framework
Learn More
Mastering ABP Framework Book
Made with ā¤ļø on ABP v10.3.0-preview. Updated on March 13, 2026, 12:51
1
ABP Assistant
šŸ” You need to be logged in to use the chatbot. Please log in first.