How to use HttpClient for File Manager

Hello,

Imagine a client program that has declared HttpClient (often scoped) that you would wire to FileManager in order to be able to pass Headers before invoking FileManager, actually it seems impossible to get HttpClient from a distant injected service because I suspect FileManager to ignore default HttpClient.

Is it possible to add a new parameter to FileManager for using an HttpClient please?


@inject HttpClient Client
@using Syncfusion.Blazor.FileManager
@inject IJSRuntime jsRuntime


<div class="control-section">
    <SfFileManager ID="file-manager" TValue="FileManagerDirectoryContent" View="ViewType.Details">
        <FileManagerAjaxSettings Url="/api/SampleData/FileOperations"
                                 UploadUrl="/api/SampleData/Upload"
                                 DownloadUrl="/api/SampleData/Download"
                                 GetImageUrl="/api/SampleData/GetImage">
        </FileManagerAjaxSettings>
    </SfFileManager>
</div>
@code {
    protected override void OnInitialized()
    {
        Client.BaseAddress ??= new Uri("http://localhost:61811");
        Client.DefaultRequestHeaders.Add("DestSubPath", "E5000");
    }
}

Thanks


14 Replies

SP Sowmiya Padmanaban Syncfusion Team October 11, 2021 12:09 PM UTC

Hi Gerome 
  
Greetings from Syncfusion support.  
  
We have checked your query in File Manager component. We have prepared a simple sample to send authorization header in OnSend event. OnSend event is triggered before sending data to the server side.  
 
Refer to the below code snippet.  
 
index.razor

<
SfFileManager TValue="FileManagerDirectoryContent">   
            . . .
    <FileManagerEvents TValue="FileManagerDirectoryContent" OnSend="onsend"></FileManagerEvents>   
</SfFileManager>   
@code{   
    void onsend(BeforeSendEventArgs args)   
    {   
        args.HttpClientInstance.DefaultRequestHeaders.Add("Authorization""user");   
    }   
}

--------------------------------------------------
FileManagerController.cs

 
public object FileOperations([FromBody] FileManagerDirectoryContent args)   
        {   
           //to sent data at server side   
    
            var val = HttpContext.Request.Headers["Authorization"];    
            }   
 
 
 
Kindly check whether the above details help you. If not, we request you to share some additional details on the following to proceed further.  
  
1.  Share the screenshot or video footage demonstrating your requirement. 
2.  Elaborate on your use case scenario to use HttpClient with File Manager. 
3.  If possible, modify the above sample similar to your scenario of using HttpClient. 
  
These details would help us to assist you promptly.  
  
Regards,  
Sowmiya.P 



GE Gerome October 11, 2021 02:06 PM UTC

Hi Sowmiya ,

Thanks for your answear. The solution you've provided works well for UPLOAD and for FILEOPERATIONS using OnSend event, I can send HttpContext.Request.Headers with success and I can retrieve from these 2 operations only.

Please, can you advise me how to do same with DOWNLOAD and GETIMAGE, because it seems not to work, when I try to get HttpContext.Request.Headers from these, I don't get any data.
Is there any event like OnSend does for these 2 last operations please?

Thanks

Regards



IL Indhumathy Loganathan Syncfusion Team October 12, 2021 01:57 PM UTC

Hi Gerome, 
 
We have validated your requirement in File Manager component. Currently we have support to send authorization header value from client to server in the OnSend event of File Manager for both Read and Upload operations. We don’t have any direct support to pass custom value for Download and GetImage operations. Please find the answer for your queries.   
   
Query 1: How to send custom value to Download operation   
   
Since there is no direct way to pass custom value, you can prevent our default download operation by setting args.Cancel as true in BeforeDownload event. Then you can trigger the customized download operation using an interop call where you can pass custom values to server side. Check out the below code snippet.    
    
[Index.razor]   
public async Task beforeDownload(BeforeDownloadEventArgs<FileManagerDirectoryContent> args)    
{    
    args.Cancel = true;    
    DirectoryContent[] data = new DirectoryContent[]{ new DirectoryContent()    
    {    
        Name = args.Data.DownloadFileDetails[0].Name, // name of the file    
        IsFile = args.Data.DownloadFileDetails[0].IsFile, // indicates whether file or folder    
        FilterPath = args.Data.DownloadFileDetails[0].FilterPath, // path of the file/folder from root directory    
        HasChild = args.Data.DownloadFileDetails[0].HasChild, // if folder has child folder set as true else false    
        Type = args.Data.DownloadFileDetails[0].Type // empty string for folder and file type like .png for files    
    
    } };    
    DownloadUrl = https://localhost:44355/api/FileManager/Download;    
    DirectoryContent downloadData = new DirectoryContent()    
    {    
        Data = data,    
        Path = args.Data.Path,// path in which the file is located (make ensure to add the path from root directory excluding the root directory name)    
        Names = args.Data.Names// names of the files to be downloaded in the specified path    
    };    
    await jsRuntime.InvokeAsync<object>("saveFile", downloadData, DownloadUrl);    
}    
   
[_Host.cshtml]    
<script>    
        window.saveFile = (data, downloadUrl) => {    
            //creating the data to call download web API method    
            var i = {    
                action: "download",    
                path: data.path,    
                names: data.names,    
                data: data.data,    
                customvalue: "TestFolder",    
            }    
            …    
            //appeding the dynamically created form to the document and perform form sumbit to perform download operation    
            a.appendChild(s),    
                document.body.appendChild(a),    
                document.forms.namedItem("downloadForm").submit(),    
                document.body.removeChild(a)    
        }    
    </script>    
   
[FileManageController.cs]    
public class FileManagerDirectoryContentExtend : FileManagerDirectoryContent    
{    
    public string customvalue { get; set; }    
}    
...    
[Route("Download")]   
public IActionResult Download(string downloadInput)   
{   
            FileManagerDirectoryContentExtend args = JsonConvert.DeserializeObject<FileManagerDirectoryContentExtend>(downloadInput);   
            var val = args.customvalue;   
  
    
Query 2: How to send token to GetImage operation    
    
We are unable to add the custom header in GetImage request since the GetImage is processed using query string parameter and download processed using form element.    
     
If we are going to use ajax (asynchronous request) then, each image creates individual request and its having certain time delay based on image size, network bandwidth and server respond time. We are unable to update the headers to the corresponding image tag value. So, it is not possible to implement these operations using Ajax requests.

It is not feasible to provide support to add custom header in GetImage request. Please let us know if you need any further assistance.
    
    
Regards,    
Indhumathy L 



GE Gerome October 18, 2021 09:36 AM UTC

Hi Indhumathy,


Thanks for your reply.

I still maintain my original question because HttpClient contains all about connected client provides like his claims and more..

That is to say that actually the Filemanager's controller is quite stressing because in any way I am unable to retrieve the HttpClient's claims, so impossible to control/block at controller's side the access of the controller, that I consider as a real security issue in a production environment, plus unable to get any extra infos that HttpClient contains

Regards,





IL Indhumathy Loganathan Syncfusion Team October 19, 2021 02:48 PM UTC

Hi Gerome, 
 
As mentioned in our previous update with similar requirement , you can pass authorization header value in HttpClient for both Read and Upload operation. For Download operation, you can pass custom value to perform Authorization at controller part. 
 
From the shared details, we are unable to identify your exact requirement in File Manager. 
 
1.      Whether you want to access all the default HttpClient properties at File Manager controller. 
 
2.      Whether do you want to perform user-based Authorization at controller side by sending header value from client to server. 
 
Please revert with your exact use case scenario to further validate on your requirement with File Manager component. 
 
Regards, 
Indhumathy L


GE Gerome October 19, 2021 06:22 PM UTC

Hi Indhumathy,


sorry if my request seems fuzzy but I can take a comparison to make you understand the very problem I am facing.


At 1st, I have an ASPNET 5 Core server that holds all API Endpoints with a generic CRUD that allows me to use WebAssembly Blazor apps where a page is using a DataGrid in CustomDataAdaptor mode

AdaptorInstance="typeof(IWasmDataAdaptor<TEntity>)"


Behind this interface that holds DatagridCrud + holds an injected service...


// Add ProxyAdaptor (based on generic open type)

builder.Services.AddScoped(typeof(IWasmProxyAdaptor<>), typeof(WasmProxyAdaptor<>));


So, the class is:

public WasmProxyAdaptor(HttpClient clientHttp)

As you can see as I've injected this class to Startup, I can de facto use the injected HppClient from my Wasm App.


What's inside my HttpClient?

Everything about once I'm logged and authorized, I can use my Claims(), so I can use the HttpClient's instance to talk with my ASPNET Core server APIs!

I realy found the way that Datagrid is implemented because it allows us to use HttpClient.


Now to the FileManager... I've seen that internally we can do this:


private void OnSend(BeforeSendEventArgs args)
{
  if (!args.HttpClientInstance.DefaultRequestHeaders.Any(x => x.Key.Equals("EnvId", StringComparison.OrdinalIgnoreCase)))
   {
    args.HttpClientInstance.DefaultRequestHeaders.Add("EnvId", EnvId + "/");
   }
 }

Nice at first sight... but in reality I am able to intercept extra parameters via IHttpContextAccessor


public FileController(IConfiguration configuration, IHttpContextAccessor accessor)
{
  _accessor = accessor;
  operation.RootFolder($"{basePath}{_accessor.HttpContext.Request.Headers["EnvId"]}");
}

Ok, nice, but... ? only that!

I can't intercept HttpClient because if i try to get 'injected' HttpClient => it is empty, no claims, no headers, well nothing, so I can't really use the component the easy way and really straightforward Datagrid component.


IMHO, it would be nice to be able to 'wire' the internal FileManager's so called HttpClient to an injected HttpClient, for Wasm client apps that are connected and authorized, then we can easily manipulate extra headers, but also get claims and manage correctly the whole machinery.


Hope my explanations enlights



Regards



SS Sharon Sanchez Selvaraj Syncfusion Team October 20, 2021 02:29 PM UTC

Hi Gerome, 
 
Thanks for the details. 
 
Based on the shared details, we understand that you would like to access the header value through HttpClient details from the server side rather than using HttpContext as given in the forum update. We need additional time to analyze on this scenario. We will check and provide further details on 25th October, 2021. 
 
We appreciate your patience. 
 
Regards. 
Sharon Sanchez S. 



IL Indhumathy Loganathan Syncfusion Team October 25, 2021 12:42 PM UTC

Hi Gerome, 
 
Thanks for your patience.  
 
We have validated your requirement to retrieve the header values from HttpClient. In File Manager, we have used HttpClient for Web API calls to perform all file operations. By using this API call, we have displayed all files and folders inside the File Manager component. To send headers in request, we have created a HttpClientInstance property inside the OnSend event args which is the exact replica of HttpClient. 
 
You can set the header or any other HttpClient properties by using the args.HttpClientInstance in OnSend event and retrieve them at server side by using HttpContext. You can’t retrieve the default HttpClient property values within File Manager controller part since we make an internal HttpClient call to render File Manager. 
 
Please check the below code snippet. 
 
[index.razor]

<
SfFileManager TValue="FileManagerDirectoryContent">    
            . . .
    <FileManagerEvents TValue="FileManagerDirectoryContent" OnSend="onsend"></FileManagerEvents>    
</SfFileManager>    
@code{    
    void onsend(BeforeSendEventArgs args)    
    {    
        args.HttpClientInstance.DefaultRequestHeaders.Add("Authorization""user");    
    }    
}
--------------------------------------------------
[FileManagerController.cs]

 
public object FileOperations([FromBody] FileManagerDirectoryContent args)    
        {    
           //You can retrieve the header value at controller side.    
            var val = HttpContext.Request.Headers["Authorization"];     
         }    
 
So kindly follow the suggested solution in your end. Please get back to us, if you need any further assistance. 
 
Regards, 
Indhumathy L


GE Gerome October 25, 2021 02:32 PM UTC

Hi Indhumathy ,

This is exactly what I've done BUT BUT BUT I'm sorry to tell you that OnSend will ONLY work for getting the files initially, but NOT for other operations (Download...) since the instance is not trappable because 'internally' managed by the component... relly annoy

So, the 'onboarded' args.HttpClientInstance is not sufficient, because I ALWAYS need user's Claims each time the Controller is reached, so your solution is a half solution, not acceptable for managing/challenging Claims() at every stage from the controller.


So my request remains same about HttpClient 'globally', because when you are developping in WebAssembly, the only 'controllers' available are distant, the examples given in the official doc aere optimistic and relies upon a Blazor Server app, but are half usable for a Wasm project.


Regards



KR Keerthana Rajendran Syncfusion Team October 26, 2021 11:38 AM UTC

Hi Gerome,  

We have created an incident under your Direct-Trac account for your last query with File Manager. We request you to follow that incident for further technical assistance.  

Regards, 
Keerthana R. 



GE Gerome October 26, 2021 11:50 AM UTC

Hi Keerthana,

Thanks, really needed.


Regards



RP Ranjani Prabakaran Syncfusion Team October 27, 2021 05:58 AM UTC

Hi Gerome, 
  
You are welcome. We are happy to assist you. 
  
Regards, 
  
Ranjani 



MH Mike Hauck April 29, 2022 08:14 PM UTC

Hi,


I am facing the same issue that Gerome describes in this thread.  Was there a solution provided that can be shared here?


Thank you,


Mike



IL Indhumathy Loganathan Syncfusion Team May 2, 2022 12:37 PM UTC

Hi Mike,


As per current implementation of File Manager component, the HttpClient instance is only sent in Read and Upload operation since we have handled only those file operations using Http request. You can use the OnSend event to set HttpClientInstance for both Read and Upload operation. 


The Download operation of File Manager is handled by using form submit and GetImage operation is handled by using query parameter. We doesn’t handle it by using Http request, so it is not possible to pass the HttpClientInstance here. However, you can send custom values from client to server for Download operation. You can prevent our default download operation by setting args.Cancel as true in BeforeDownload event. Then you can trigger the customized download operation using an interop call where you can pass custom values to server side. Please check the below update.


http://www.syncfusion.com/forums/169552/how-to-use-httpclient-for-file-manager?reply=SoZ8Dd


This is the current behavior of File Manager component. Please check the shared details and get back to us if you need any further assistance.


Regards,

Indhumathy L


Loader.
Up arrow icon