We use cookies to give you the best experience on our website. If you continue to browse, then you agree to our privacy policy and cookie policy. Image for the cookie policy date

Get response when Upload File

Hello,

I have an Action that process the file uploaded and returns a Dto with aditional info about the image. 

  1. There are some way to get the Dto? 
  2. My Action add a custom header on my response. But when I try get the header on the control, it is empty.

                <SfUploader AutoUpload="false">
                    <UploaderAsyncSettings SaveUrl="https://localhost:44361/api/customer/uploadfile"></UploaderAsyncSettings>
                    <UploaderEvents Success="OnSuccess"></UploaderEvents>
                </SfUploader>

@code
{
    private void OnSuccess(SuccessEventArgs args)
    {
        if (args.Operation == "upload")
        {
            var myDto = args.Response.XXXXX;
            args.Response.Headers //Always its empty
        }        
    }
}

16 Replies

PM Ponmani Murugaiyan Syncfusion Team April 27, 2020 08:53 AM UTC

Hello Carlos, 
 
Greetings from Syncfusion support. 
 
We can pass the custom data in the response header and get the passed data in the success event arguments form args.Response.Headers. Please find the code snippet and test sample below for your reference.   
 
[Index.razor] 
 
    <SfUploader ID="UploadFiles" AutoUpload="false"> 
    <UploaderEvents Success="OnSuccess"></UploaderEvents> 
    <UploaderAsyncSettings SaveUrl="api/SampleData/Save" RemoveUrl="api/SampleData/Remove"></UploaderAsyncSettings> 
</SfUploader> 
@code{ 
 
    public void OnSuccess(SuccessEventArgs args) 
    { 
        var customHeader = args.Response.Headers.Split(new Char[] { '\n' })[1]; // To split the response header values 
        var key = customHeader.Split(new Char[] { ':' })[0]; // To get the key pair of provided custom data in header 
        var value = customHeader.Split(new Char[] { ':' })[1].Trim(); // To get the value for the key pair of provided custom data in header 
        } 
} 
 
 
 
Server side 
 
[HttpPost("[action]")] 
    public async void Save(IList<IFormFile> UploadFiles) 
    { 
        try 
        { 
            foreach (var file in UploadFiles) 
            { 
                if (UploadFiles != null) 
                { 
                    var filename = ContentDispositionHeaderValue.Parse(file.ContentDisposition).FileName.Trim('"'); 
                    filename = hostingEnv.WebRootPath + $@"\{filename}"; 
                    if (!System.IO.File.Exists(filename)) 
                    { 
                        using (FileStream fs = System.IO.File.Create(filename)) 
                        { 
                            file.CopyTo(fs); 
                            fs.Flush(); 
                        } 
                    } 
                    else 
                    { 
                        Response.Clear(); 
                        Response.StatusCode = 204; 
                        Response.HttpContext.Features.Get<IHttpResponseFeature>().ReasonPhrase = "File already exists."; 
                    } 
                } 
            } 
            Response.Headers.Add("ID", "custom_ID"); // Assign the custom data in the response header. 
        } 
        catch (Exception e) 
        { 
            Response.Clear(); 
            Response.ContentType = "application/json; charset=utf-8"; 
            Response.StatusCode = 204; 
            Response.HttpContext.Features.Get<IHttpResponseFeature>().ReasonPhrase = "No Content"; 
            Response.HttpContext.Features.Get<IHttpResponseFeature>().ReasonPhrase = e.Message; 
        } 
         
    } 
 
 
 
Kindly check with the above sample. If you need further assistances, please get back us. 
 
Regards, 
Ponmani M 



ZM zmp July 1, 2022 01:53 PM UTC

Hi, What if I don't want the headers? I just want my plain Json text returned by the Action?




SP Sureshkumar P Syncfusion Team July 4, 2022 07:29 AM UTC

Hi Carlos,

We suggest you remove the Response.Clear and Response.ContentType from your server-side code to achieve your requirement. 

[Server Side ]

 

public IActionResult OnPostUpload(IList<IFormFile> uploadFiles)

{

   //... 

        // no need to update the Response here  

        @* Response.Clear(); 

        Response.ContentType = "application/json"; *@ 

        // Sennd HTTP 200 (OK), 400, or what you want. 

        return StatusCode(204, new { Message = $"{errorMessage}" }); 

}

 

[Client Side]

    function onUploadSuccess(args) {

        let response = JSON.parse(args.e.target.response);

        args.statusText = response.message;

    }

 

    function onUploadFail(args) {

        let response = JSON.parse(args.e.target.response);

        args.statusText = response.message;

    }

 

Regards,

Sureshkumar P



ZM zmp replied to Sureshkumar P July 6, 2022 08:23 PM UTC

Hello Sureshkumar

I believe you sent an example of Javascript framework, and the question is about Blazor


Any way, I got the idea but in Blazor we have the event Success which returns a 

SuccessEventArgs


But the args.E object only returns   {"isTrusted":true}





SP Sureshkumar P Syncfusion Team July 7, 2022 05:49 AM UTC

Hi ZMP,

Sorry for the misunderstanding your requirement. We can get the backed response from our blazor uploader success evet using args.Response as like the below screen shot.

Find the screen shot here:

Find the screen shot of the response property:



Regards,

Sureshkumar P



ZM zmp replied to Sureshkumar P July 7, 2022 12:50 PM UTC

Hello Sureshkhumar, thanks for the quick response.


Well as you can see I have no information here about the response body:



I only got the header and the StatusCode

But as you can see here, I've got a response body(raw response) when inspecting the called method from the Browser


I'm trying to read that response from the SuccessEventArgs but I have no "Success" in it



SP Sureshkumar P Syncfusion Team July 8, 2022 12:07 PM UTC

Hi Zmp,

We cannot achieve your requirement as a default uploading process. So we have created a custom sample to achieve your requirement. In this sample, we have got the selected files using the uploader change event and call the server by using the PostAsync method.

From the server end, we have saved the file and returned the result using the UploadResult class type. Then display the resulted data on the view page.

Find the code example here:

[counter.razor]

<SfUploader ID="upload">

<UploaderEvents ValueChange="@OnInputFileChange">UploaderEvents>

SfUploader>

<h1>Upload Filesh1>

@if (files.Count > 0)

{

<div class="card">

<div class="card-body">

<ul>

@foreach (var file in files)

{

<li>

File: @file.Name

<br>

@if (FileUpload(uploadResults, file.Name, Logger,

out var result))

{

<span>

Stored File Name: @result.StoredFileName

span>

}

else

{

<span>

There was an error uploading the file

(Error: @result.ErrorCode).

span>

}

li>

}

ul>

div>

div>

}

@code {

private List files = new List();

private List uploadResults = new List();

private int maxAllowedFiles = 3;

private bool shouldRender;

protected override bool ShouldRender() => shouldRender;

private async Task OnInputFileChange(UploadChangeEventArgs args)

{

shouldRender = false;

long maxFileSize = 1024 * 1024 * 15;

var upload = false;

using var content = new MultipartFormDataContent();

foreach (var file in args.Files)

{

if (uploadResults.SingleOrDefault(

f => f.FileName == file.FileInfo.Name) is null)

{

try

{

var fileContent =

new StreamContent(file.Stream);

fileContent.Headers.ContentType =

new MediaTypeHeaderValue(file.FileInfo.MimeContentType);

files.Add(new File() { Name = file.FileInfo.Name });

content.Add(

content: fileContent,

name: "\"files\"",

fileName: file.FileInfo.Name);

upload = true;

}

catch (Exception ex)

{

Logger.LogInformation(

"{FileName} not uploaded (Err: 6): {Message}",

file.FileInfo.Name, ex.Message);

uploadResults.Add(

new UploadResult()

{

FileName = file.FileInfo.Name,

ErrorCode = 6,

Uploaded = false

});

}

}

}

if (upload)

{

var client = ClientFactory.CreateClient();

var response =

await client.PostAsync("https://localhost:44394/api/Filesave",

content);

if (response.IsSuccessStatusCode)

{

var options = new JsonSerializerOptions

{

PropertyNameCaseInsensitive = true,

};

using var responseStream =

await response.Content.ReadAsStreamAsync();

var newUploadResults = await JsonSerializer

.DeserializeAsync<IList<UploadResult>>(responseStream, options);

if (newUploadResults != null)

{

uploadResults = uploadResults.Concat(newUploadResults).ToList();

}

}

}

shouldRender = true;

}

private static bool FileUpload(IList<UploadResult> uploadResults,

string? fileName, ILogger<Counter> logger, out UploadResult result)

{

result = uploadResults.SingleOrDefault(f => f.FileName == fileName);

if (!result.Uploaded)

{

logger.LogInformation("{FileName} not uploaded (Err: 5)", fileName);

result.ErrorCode = 5;

}

return result.Uploaded;

}

private class File

{

public string? Name { get; set; }

}

public class UploadResult

{

public bool Uploaded { get; set; }

public string? FileName { get; set; }

public string? StoredFileName { get; set; }

public int ErrorCode { get; set; }

}

}

[FilesSaveController.cs]

namespace BlazorApp1.Data

{

public class UploadResult

{

public bool Uploaded { get; set; }

public string FileName { get; set; }

public string StoredFileName { get; set; }

public int ErrorCode { get; set; }

}

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

[ApiController]

public class FilesaveController : ControllerBase

{

private readonly IWebHostEnvironment env;

private readonly ILogger logger;

public FilesaveController(IWebHostEnvironment env,

ILogger logger)

{

this.env = env;

this.logger = logger;

}

[HttpPost]

public async Task>> PostFile(

[FromForm] IEnumerable files)

{

var maxAllowedFiles = 3;

long maxFileSize = 1024 * 1024 * 15;

var filesProcessed = 0;

var resourcePath = new Uri($"{Request.Scheme}://{Request.Host}/");

List uploadResults = new List();

foreach (var file in files)

{

var filename = ContentDispositionHeaderValue

.Parse(file.ContentDisposition)

.FileName

.Trim('"');

var uploadResult = new UploadResult();

string trustedFileNameForFileStorage;

var untrustedFileName = file.FileName;

uploadResult.FileName = untrustedFileName;

var trustedFileNameForDisplay =

WebUtility.HtmlEncode(untrustedFileName);

if (filesProcessed < maxAllowedFiles)

{

try

{

trustedFileNameForFileStorage = file.FileName;

var path = this.env.ContentRootPath;

filename = path + $@"\{trustedFileNameForFileStorage}";

using FileStream fs = new FileStream(filename, FileMode.Create);

file.CopyTo(fs);

logger.LogInformation("{FileName} saved at {Path}",

trustedFileNameForDisplay, path);

uploadResult.Uploaded = true;

uploadResult.StoredFileName = trustedFileNameForFileStorage;

}

catch (IOException ex)

{

logger.LogError("{FileName} error on upload (Err: 3): {Message}",

trustedFileNameForDisplay, ex.Message);

uploadResult.ErrorCode = 3;

}

filesProcessed++;

}

else

{

logger.LogInformation("{FileName} not uploaded because the " +

"request exceeded the allowed {Count} of files (Err: 4)",

trustedFileNameForDisplay, maxAllowedFiles);

uploadResult.ErrorCode = 4;

}

uploadResults.Add(uploadResult);

}

return new CreatedResult(resourcePath, uploadResults);

}

}

}

Find the sample in the attachment:

Regards,

Sureshkumar P


Attachment: BlazorApp1_9e8c35e5.zip



ZM zmp July 8, 2022 01:08 PM UTC

Hello SureShkumar, thanks for the answer!

" We cannot achieve your requirement as a default uploading process." Sorry to hear that


About the sample you sent, I've already tried something similar (and have tested yours) but the case is I'm sending large files with 500 mb

which is not much for the actuals internet performance nowadays. And by doing a manual upload like the sample you sent, it takes really much longer. Even If I don't send it through, it takes a long time just loading.


Could we make a feature request so the SfUploader return the Response Body on the SuccessEventArgs?




SP Sureshkumar P Syncfusion Team July 12, 2022 02:15 PM UTC



SP Sureshkumar P Syncfusion Team July 13, 2022 11:58 AM UTC

Hi Zmp,

We have logged “Provide support for catch the returned response body in uploader component” this is a feature request and this support will be included in any one of our upcoming releases.

You can track the status of this feature from the below feedback link.

Feedback Link: https://www.syncfusion.com/feedback/36284


Regards,

Sureshkumar P



ZM zmp July 13, 2022 12:00 PM UTC

Hello Sureshkumar 

That's great news!

Thank you for the support




SP Sureshkumar P Syncfusion Team July 14, 2022 06:51 AM UTC

Zmp,


Thanks for your update.


Regards,

Sureshkumar P



SW Steve Wong August 26, 2022 10:14 PM UTC

I would find this feature useful as well.  



SP Sureshkumar P Syncfusion Team August 29, 2022 06:44 AM UTC

Steve,


Thanks for your update.


Regards,

Sureshkumar P



SU suresh September 27, 2022 08:02 AM UTC

Dear Syncfusion support team

When will we get this feature ?

Regards

Suresh Vasu




SP Sureshkumar P Syncfusion Team September 28, 2022 07:41 AM UTC

Hi Suresh,

As previously stated, we would investigate the feature and integrate it in a future release based on the number and priority of client requests. As a result, once the route map is ready, we will notify you. The feedback link can be used to follow the status of the feature.

Please upvote these features to make this our priority. We will prioritize the features every release, based on the user demands.

Regards,

Sureshkumar P


Loader.
Up arrow icon