Model Binding & Custom error issues with File Manager

Hello,

I am currently using File Manager in a Blazor Web Assembly solution and ran into some issues.

1.Model binding issue: On the upload call I saw the parameters are sent on the form data.

The problem what I have is that even though I am adding the [FromForm] attribute on the controller method parameters they are coming up as null. The only way I was able to get them was by accessing the Request.Form dictionary and deserialize the objects manually.

2. Custom error issue: Taken from a sample project, I saw that on the upload method you can modify the response so that you are sending a custom error message. I am trying to introduce a validation that stops the user from uploading files if there are more than 5 on the specific repository.



While the status code comes through(and I noticed when using 400 status code the component defaults to a "file already exists" pop-up), the custom error message is not displayed anywhere.

Is there any way of modifying the default "File failed to upload" message?


As an alternative, I have tried to do this by triggering a javascript interop method to modify the message on the onerror event, but I was able to modify the message only using a timeout function. For some reason the onchange event on the file status span does not trigger when changing the status from "Uploading" to "File failed to upload".

I have attached a sample project demonstrating these issues.


Thank you,

Vlad S.
Attachment: BlazorClient3_5a08c9b6.zip


11 Replies

IL Indhumathy Loganathan Syncfusion Team February 4, 2022 03:04 PM UTC

Hi Vlad, 
 
Greetings from Syncfusion support. 
 
Please find the details for your queries below. 
 
Query 1: How to get additional attributes in Upload operation. 
 
We suggest you to use HttpClientInstance to send and retrieve additional attributes in File Manager component. For your reference, we have modified the sample to send blob path for Upload operation. Check the below code snippet. 
 
private void OnSend(BeforeSendEventArgs args) 
{ 
    //send additional attribute values. 
    args.HttpClientInstance.DefaultRequestHeaders.Add("BlobFolder", "SampleFolder"); 
} 
... 
// uploads the file(s) into a specified path 
[Route("Upload")] 
public IActionResult Upload(string path, IList<IFormFile> uploadFiles, string action) 
{ 
    //You can retrieve the header value at controller side.    
    string val = HttpContext.Request.Headers["BlobFolder"].ToString().Split(',')[0]; 
 
Query 2: How to set customer error message. 
 
In File Manager, you can change the default upload failure error before returning the upload response. Check the below code snippet. 
 
// uploads the file(s) into a specified path 
        [Route("Upload")] 
        public IActionResult Upload(string path, IList<IFormFile> uploadFiles, string action) 
        { 
            FileManagerResponse uploadResponse; 
            uploadResponse = operation.Upload(path, uploadFiles, action, null); 
            if (uploadResponse.Error != null) 
            { 
               Response.Clear(); 
               Response.ContentType = "application/json; charset=utf-8"; 
               Response.StatusCode = Convert.ToInt32(uploadResponse.Error.Code); 
               Response.HttpContext.Features.Get<IHttpResponseFeature>().ReasonPhrase = "Custom error message"; 
            } 
            return Content(""); 
        } 
 
Check the below sample for reference. 
 
 
Please let us know if you need any further assistance. 
 
Regards, 
Indhumathy L 



VS Vlad Sucala February 7, 2022 12:42 PM UTC

Hello Indhumathy,


Thank you for your reply. For the first issue I will follow your advice and will use the request headers, thank you.

For the second issue, as mentioned in the initial post, I do not see that custom error message being displayed anywhere? 

I see the initial dialog that is asking me what to do with the file(this happens when using 400 status code).


And after that I see the image I provided in the original post with the file failed to upload message.


Even looking at the upload call in the network tab I see no trace of the custom error message.

Where should I expect to see the custom error message?


Thank you,

Vla



IL Indhumathy Loganathan Syncfusion Team February 8, 2022 02:42 PM UTC

Hi Vlad, 
 
The reported error message triggers from Uploader component which is integrated internally within File Manager to perform Upload operation. Currently we are checking the feasibility to override that error message in the File Manager component. We will update you further details on or before February 11, 2022. 
 
We appreciate your patience. 
 
Regards, 
Indhumathy L 



IL Indhumathy Loganathan Syncfusion Team February 11, 2022 02:44 PM UTC

Hi Vlad, 

Currently, we don’t have direct support to overwrite the mentioned Upload failure error in File Manager. However, we have considered this requirement as a feature at our end, and it will be included in any of our upcoming releases. Generally, we will plan any feature implementation based on customer request count, feature rank, and wish list plan. 

You can track the feature status through the below link, 
 
 
Regards, 
Indhumathy L 



ME Mehmet Emre February 4, 2024 01:01 PM UTC

I'm having the same problem.

Download and upload not working.

Bad request to distribute data as null returns 400

While uploading, at first it seems as if the file exists, just like the problem experienced above. However, there is no file and the directory is empty.

3.png


1.png

----------------blazor-----------------------

<SfFileManager TValue="FileManagerDirectoryContent">

       <FileManagerAjaxSettings Url="http://localhost:5008/api/Demirbas/FileOperations"

                             UploadUrl="http://localhost:5008/api/Demirbas/Upload"

                             DownloadUrl="http://localhost:5008/api/Demirbas/Download">

    </FileManagerAjaxSettings>

    <FileManagerNavigationPaneSettings Visible="false" />

</SfFileManager>


------Api----------------

    public class DemirbasController : ControllerBase

    {

        private readonly IDemirbasService _demirbasService;

        public PhysicalFileProvider operation;

        public string basePath;

        string root = "\\Content\\File";


        [Obsolete]

        public DemirbasController(IDemirbasService demirbasService, Microsoft.AspNetCore.Hosting.IHostingEnvironment hostingEnvironment)

        {

            _demirbasService = demirbasService;

            this.operation = new PhysicalFileProvider();

            this.basePath = hostingEnvironment.ContentRootPath;

            this.operation.RootFolder(this.basePath + this.root);

        }

   [AllowAnonymous]

   [Route("FileOperations")]

   public object FileOperations([FromBody] FileManagerDirectoryContent args)

   {

       string path = basePath + "\\Content\\File\\" + args.Path;


       if (!Directory.Exists(path))

           Directory.CreateDirectory(path);


       switch (args.Action)

       {

           case "read":


               // reads the file(s) or folder(s) from the given path.


               return this.operation.ToCamelCase(this.operation.GetFiles(args.Path, args.ShowHiddenItems));


           case "delete":


               // deletes the selected file(s) or folder(s) from the given path.


               return this.operation.ToCamelCase(this.operation.Delete(args.Path, args.Names));


           case "copy":


               // copies the selected file(s) or folder(s) from a path and then pastes them into a given target path.


               return this.operation.ToCamelCase(this.operation.Copy(args.Path, args.TargetPath, args.Names, args.RenameFiles, args.TargetData));


           case "move":


               // cuts the selected file(s) or folder(s) from a path and then pastes them into a given target path.


               return this.operation.ToCamelCase(this.operation.Move(args.Path, args.TargetPath, args.Names, args.RenameFiles, args.TargetData));


           case "details":


               // gets the details of the selected file(s) or folder(s).


               return this.operation.ToCamelCase(this.operation.Details(args.Path, args.Names, args.Data));


           case "create":


               // creates a new folder in a given path.


               return this.operation.ToCamelCase(this.operation.Create(args.Path, args.Name));


           case "search":


               // gets the list of file(s) or folder(s) from a given path based on the searched key string.


               return this.operation.ToCamelCase(this.operation.Search(args.Path, args.SearchString, args.ShowHiddenItems, args.CaseSensitive));


           case "rename":


               // renames a file or folder.


               return this.operation.ToCamelCase(this.operation.Rename(args.Path, args.Name, args.NewName));


       }

       return null;


   }


   [AllowAnonymous]


   [Route("Download")]

   public async Task<IActionResult> Download(string downloadInput)

   {


       FileManagerDirectoryContent args = JsonConvert.DeserializeObject<FileManagerDirectoryContent>(downloadInput);

       return operation.Download("/" + args.Path + "/", args.Names);

   }



   [AllowAnonymous]

   [Route("Upload")]

   public IActionResult Upload(string path,IList<IFormFile> uploadFiles,string action)

   {


       //FileManagerResponse uploadResponse;

       //uploadResponse = operation.Upload(path, uploadFiles, action, null);

       //if (uploadResponse.Error != null)

       //{

       // Response.Clear();

       // Response.ContentType = "application/json; charset=utf-8";

       // Response.StatusCode = Convert.ToInt32(uploadResponse.Error.Code);

       // Response.HttpContext.Features.Get<IHttpResponseFeature>().ReasonPhrase = uploadResponse.Error.Message;

       //}

       return Content("");

   }




PM Prasanth Madhaiyan Syncfusion Team February 5, 2024 10:00 AM UTC

Hi Mehmet,


Based on the shared details, we have prepared the Blazor FileManager sample with the Physical file system provider in the latest package version. Upon testing the Download and Upload functionalities in the prepared FileManager sample, we found that both functions worked properly without any issues.


For your reference, we have attached the sample and provider.


Sample: Attached as a zip file.


Physical provider: https://github.com/SyncfusionExamples/ej2-aspcore-file-provider


Please check out the attached sample. If the issue still persists, could you please replicate the issue in the attached sample or share the replicated sample of the issue? Based on that, we will investigate and provide you with a prompt solution. Kindly get back to us with the requested details.


Regards,

Prasanth Madhaiyan.


Attachment: BlazorFileManagerSample_69a96e5e.zip


ME Mehmet Emre February 8, 2024 01:44 PM UTC

 Hello Prasanth 

I updated it to the latest version, but unfortunately the data continues to come up empty.


(FileManagerDirectoryContent args) comes full, there is no problem there, but when downloading and uploading, the data that should come is null.


I am using .net 8 blazor wasm.

I am using .net 7 api server located on localhost.


I think wasm is not sending the correct data to the server.


Alternatively, how can I send downloadInput data to the server?


333-min.jpg

22.jpg

API RETURN STACK

  • ArgumentNullException: Value cannot be null. (Parameter 'value')

    • Newtonsoft.Json.Utilities.ValidationUtils.ArgumentNotNull(object value, string parameterName)

    • Newtonsoft.Json.JsonConvert.DeserializeObject(string value, Type type, JsonSerializerSettings settings)

    • Newtonsoft.Json.JsonConvert.DeserializeObject<T>(string value, JsonSerializerSettings settings)

    • Newtonsoft.Json.JsonConvert.DeserializeObject<T>(string value)

    • PERP.API.Controllers.DemirbasController.Download(string downloadInput) in DemirbasController.cs

      1. FileManagerDirectoryContent args = JsonConvert.DeserializeObject<FileManagerDirectoryContent>(downloadInput);
    • Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor+TaskOfIActionResultExecutor.Execute(ActionContext actionContext, IActionResultTypeMapper mapper, ObjectMethodExecutor executor, object controller, object[] arguments)

    • Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask<IActionResult> actionResultValueTask)

    • Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, object state, bool isCompleted)

    • Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)

    • Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted)

    • Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync()

    • Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|20_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, object state, bool isCompleted)

    • Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)

    • Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)

    • Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)

    • Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)

    • Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)

    • Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)

    • Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)

    • Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)

    • Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)

    • Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)

  • API HEADER
  • VariableValue
    Accepttext/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
    Accept-Encodinggzip, deflate, br
    Accept-Languagetr,en-US;q=0.9,en;q=0.8
    Cache-Controlno-cache
    Connectionkeep-alive
    Content-Length862
    Content-Typeapplication/x-www-form-urlencoded
    Hostlocalhost:5008
    Originnull
    Pragmano-cache
    sec-ch-ua"Not A(Brand";v="99", "Microsoft Edge";v="121", "Chromium";v="121"
    sec-ch-ua-mobile?0
    sec-ch-ua-platform"Windows"
    Sec-Fetch-Destdocument
    Sec-Fetch-Modenavigate
    Sec-Fetch-Sitecross-site
    Sec-Fetch-User?1
    Upgrade-Insecure-Requests1
    User-AgentMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36 Edg/121.0.0.0


PM Prasanth Madhaiyan Syncfusion Team February 9, 2024 07:43 AM UTC

Hi Mehmet,


Based on the shared details, we have prepared the Blazor FileManager sample in the .NET 8 Blazor WASM application, and our Physical provider is in the .NET 7 application. However, when checking, the Download and Upload functionalities are working properly without any issues at our end.


For your reference, we have attached the sample and Physical provider.


Sample: Attached as a zip file.


Physical provider: https://github.com/SyncfusionExamples/ej2-aspcore-file-provider


Please check out the attached sample. If the issue still persists, could you please replicate the issue in the attached sample or share the replicated sample of the issue? Based on that, we will investigate and provide you with a prompt solution. Kindly get back to us with the requested details.


Regards,

Prasanth Madhaiyan.


Attachment: BlazorAppWASMFileManager_d3d7c030.zip


ME Mehmet Emre February 9, 2024 05:00 PM UTC

Hi Prasanth

I tried the wasm project you sent with my own API. Unfortunately, the data comes back as null.

There are probably problems with the Api project.

Attached I am sending an example of my API project.

I'm curious where I'm making a mistake :)


Thanks a lot


Attachment: api_b724bc8d.7z


PM Prasanth Madhaiyan Syncfusion Team February 12, 2024 01:21 PM UTC

Hi Mehmet,


Based on the shared sample, we were able to replicate the mentioned scenario where downloadInput data values are null when performing the download operation in the Blazor FileManager component on our end. However, to overcome this scenario in the Blazor FileManager component, we suggest that you add explicit HttpMethod bindings to the FileManager component server methods in the controller file


Refer to the below code snippets.


[DemirbasController.cs]


namespace PERP.API.Controllers

{

    [Route("api/[controller]")]

    [EnableCors("AllowAllOrigins")]

    //[ApiController]

    //[Authorize]

    public class DemirbasController : ControllerBase

    {

       

 

        //[AllowAnonymous]

      

        [Route("FileOperations")]

        [HttpPost]

        public object FileOperations([FromBody] FileManagerDirectoryContent args)

        {

           

       

        }

 

        //[AllowAnonymous]

        [Route("Download")]

        [HttpPost]

        public IActionResult Download(string? downloadInput)

        {

            

        }

 

 

        //[AllowAnonymous]

        [Route("Upload")]

        [HttpPost]

 

        public IActionResult Upload(string? path,IList<IFormFile> uploadFiles,string? action)

        {

           

        }

 

    }

}

 


For your reference, we have attached a screenshot and your provider sample.


Screenshot:



Provider: Attached as a zip file.


Check out the attached sample and let us know if you need any further assistance.


Regards,

Prasanth Madhaiyan.



Attachment: API_95843a93.zip


ME Mehmet Emre February 12, 2024 02:41 PM UTC

Hi  Prasanth 

When I removed [ApiController] everything went back to normal.

Thanks so much for your help.


BR


Loader.
Up arrow icon