<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
}
}
|
[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;
}
}
|
Hi, What if I don't want the headers? I just want my plain Json text returned by the Action?
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
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}
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
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
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 private 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
public FilesaveController(IWebHostEnvironment env, ILogger { this.env = env; this.logger = logger; }
[HttpPost] public async Task [FromForm]
IEnumerable { var maxAllowedFiles = 3; long maxFileSize = 1024 * 1024 * 15; var filesProcessed = 0; var resourcePath = new Uri($"{Request.Scheme}://{Request.Host}/"); 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
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?
Hi Zmp,
Regards,
Sureshkumar P
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
Hello Sureshkumar
That's great news!
Thank you for the support
Zmp,
Thanks for your update.
Regards,
Sureshkumar P
I would find this feature useful as well.
Steve,
Thanks for your update.
Regards,
Sureshkumar P
Dear Syncfusion support team
When will we get this feature ?
Regards
Suresh Vasu
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