File upload inconveniences in an EditForm

Hi,

I have multiple tricks to do to use this component in an EditForm and I think it should be much easier to use.


Use case :

I have an EditForm and I want to attach file(s) with my context model and post it to the server.

Currently I need to do it in two times because I can't post a model with the attached file(s).


Current (not pratical) process :

- Use the FileSelected event to set the auth token, because SelectedEventArgs has a CurrentRequest property.

- Post the model to store it then get its ID

- Set the UploaderAsyncSettings.SaveUrl with the ID

- Post the file(s) with the UploadAsync method. It is awaitable but it is not awaiting for the server response.


What would be more convenient ?

- A better way to set headers for the uploader request. Using a auth token is pretty common.

- UploadAsync (or another method) could take an url, so that I can set the ID url parameter at the correct moment.

- UploadAsync (or another method) should wait for the server response.


Maybe I'm missing something but I didn't find a better way for this common use case.

Is it possible to consider implementing some little things to help in this case ? Or is there a better way to do it ?



Please see a repro WASM project.


Attachment: BlazorUploader_c1c8003c.zip

6 Replies

JB Julien Barach May 26, 2023 01:43 PM UTC

Hello Syncfusion Team,


Any news on this topic ?



UD UdhayaKumar Duraisamy Syncfusion Team May 30, 2023 12:57 PM UTC

The recommended method for passing additional data to the server-side using Syncfusion uploader is to pass the data using CustomFormData. Please refer to the shared forums below for further information.




JB Julien Barach June 2, 2023 06:38 AM UTC

Hi,


Thanks for the answer, but it's still not a convenient way to use this component and it looks like more of tricks than features.


At least please consider allowing to update the UploaderAsyncSettings.SaveUrl parameter. Maybe the SfUploader.UploadAsync method could take the url as a parameter.


In a form there are too much tricks on this component to make it work.

When you want to create an entity with inputs data and files, you don't have any ID, so you don't have a SaveUrl to provide.


In this (common) use case, you need to :

- Put the data in headers. Really ? in 2023 ? with the limited size Apache sets by default for the headers ?

- Hide the upload button with CSS (you don't have a SaveUrl because you don't have an entity ID yet)

- Put the Header Authorization token on the FileSelected event : Looks like weird, not like a feature

- Post the classical data to get the entity ID, then trigger StateHasChanged to make sure the SaveUrl updates and get the ID in the component's corresponding field.

- Then you trigger the UploadAsync method, but you cannot await for it, you are in the HandleValidSubmit method but you cannot redirect the user to the /entity/id because the upload is probably not finished yet.

- To do this you need to define the UploaderEvents.Success and then maybe you can redirect. Maybe because If you have more than one SfUploader you need a lot of logic to redirect when all the SfUploaders are successful. Just because we cannot await on the UploadAsync method.


Well, it's way too much for a common use case and life could be a lot easier with simple adjustments :

- Appropriate API to define (authorization) headers.

- A method to set the SaveUrl whenever we want (or as a parameter of UploadAsync)

- Be able to await UploadAsync. Meaning that when UploadAsync is finished it returns the server status (or your own success/failure status but at least we stay in the same process flow).

- A boolean to hide the upload button.


I hope you can consider these features. Tricks a sometimes OK but they need to be rare, not the rule. Please do not make Blazor feels like JS.


JB



PK Priyanka Karthikeyan Syncfusion Team July 27, 2023 01:37 PM UTC

Hi Julien,

Sorry for the inconvenience caused.

Query1: "Currently I need to do it in two times because I can't post a model with the attached file(s)." Query2: “Post the model to store it then get its ID

Avoid calling uploadAsync twice instead, you can utilize the FileSelected event to extract the file details such as the file name and ID. This way, you can pass the necessary information to the post action for further processing when submit button clicked. Please refer to the attached video for a clear demonstration.

Remember, handling the file upload process efficiently can improve user experience and reduce unnecessary server load. Using the FileSelected event ensures that you gather the required information at the right time and avoid redundant operations.

private async Task OnFileSelected(SelectedEventArgs args)

    {

      model.FileName = new List<UploaderUploadedFiles>() { new UploaderUploadedFiles() { Name = args.FilesData[0].Name, Type = args.FilesData[0].Type, Size = args.FilesData[0].Size } };

    model.FileId = currentCount++;

    }

Query3: “Appropriate API to define (authorization) headers

We have considered “Need to provide api for authorization token” as a uncertain feature request from our end and logged the report for the same and the fix will be included with any of our upcoming releases.

 You can now track the current status of the report, review the proposed resolution timeline, and contact us for any further inquiries through this link:

Feedback Link: https://www.syncfusion.com/feedback/45644/need-to-provide-api-for-authorization-token

Query4: “A method to set the SaveUrl whenever we want (or as a parameter of UploadAsync

You have the flexibility to dynamically set the SaveUrl property in the file upload control. Please find the code snippet below for your reference.

<SfButton id="displaybutton" OnClick="OnClick">Add</SfButton>

@code {
   
    private async void OnClick()
    {
        SaveUrl = "https://aspnetmvc.syncfusion.com/services/api/uploadbox/Save";
        await fileUploader.UploadAsync();
    }
}

Query5: “Be able to await UploadAsync. Meaning that when UploadAsync is finished it returns the server status (or your own success/failure status but at least we stay in the same process flow.”

When using UploadAsync method, it does not wait for the code execution to complete; instead, it acts similarly to an await statement within its scope. This means that it won't block the subsequent execution of code and allows your program to continue running other tasks.

To perform actions after the upload has completed successfully, you can utilize the Success event. This event is triggered when the file upload is done, and you can write the necessary logic or actions that need to be executed after the successful upload within the success event handler.

Query6: “A boolean to hide the upload button

If you wish to hide the upload button, you can apply the below styles.

<style>

    .e-btn.e-flat.e-primary, .e-css.e-btn.e-flat.e-primary {

        display: none;

    }

</style>

 

Documentation: https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Inputs.UploaderEvents.html#Syncfusion_Blazor_Inputs_UploaderEvents_FileSelected

https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Inputs.UploaderEvents.html#Syncfusion_Blazor_Inputs_UploaderEvents_Success

https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Inputs.UploaderAsyncSettings.html#Syncfusion_Blazor_Inputs_UploaderAsyncSettings_SaveUrl


Regards,

Priyanka K


Attachment: BlazorFileUpload_aeadef66_2d9a45da.zip


JB Julien Barach August 1, 2023 05:30 AM UTC

Hi,


Thank you for your reply.

This is actually what I'm doing and yes it's working.

I'm just saying it's a lot of tricks each time I want to use it.


I mean, each time I need to : 

- Use FileSelected to set the request header (tricks, could be a settings) : Glad you consider it.

- Hiding the upload button with CSS (tricks, could be a settings)

- Managing SaveUrl dynamically (could be a parameter to the UploadAsync method)

- Using Success to really await the upload (tricks, I need to manage some global state to tell the user it's uploading. Instead, UploadAsync should do that and it would be up to me to await it or not)


That's just a matter of what the SfUploader component could offer to simplify this common use case.

Doing all of this once in an app can be OK. But in large app with many SfUploader on different pages (some pages can have multiple SfUploader) it's a bit painful to implement.


Best Regards.


Julien



KP Kokila Poovendran Syncfusion Team August 2, 2023 11:52 AM UTC

Hi Julien Barach,


We appreciate your feedback and understand the challenges you are facing when implementing it in large applications with multiple SfUploader instances. We have taken your suggestions into consideration.


Query 1: "Hiding the upload button with CSS" - We acknowledge that this trick could be made more straightforward by providing an API or a settings option to manage the visibility of the upload button.


Query 2: "Managing SaveUrl dynamically" - You pointed out the need for an additional parameter in the UploadAsync method to handle dynamic SaveUrl.


We are actively working on these features and plan to release them along with the fix for the "Need to provide API for authorization token" issue.


 You can now track the current status through this link:

Feedback Linkhttps://www.syncfusion.com/feedback/45644/need-to-provide-api-for-authorization-token


Query 3: "Using Success to really await the upload"

As mentioned earlier, when using UploadAsync method, it does not wait for the code execution to complete; instead, it acts similarly to an await statement within its scope. This means that it won't block the subsequent execution of code and allows your program to continue running other tasks.

To perform actions after the upload has completed successfully, you can utilize the Success event. This event is triggered when the file upload is done, and you can write the necessary logic or actions that need to be executed after the successful upload within the success event handler.


Loader.
Up arrow icon