I have a solution with ASP.NET Core MVC App (8.0) & .NET Core Web API projects. The API project has a Save method that uploads the file to an Azure Storage account. Once. both projects are running, I was able to test the API Save method to upload files successfully to Azure Storage container. But when I used the ejs-uploader it always shows that the "File Failed to Upload" error. When I try to debug the issue, I don't see the Breakpoints hitting the Save method at all. I tried to Add Cors as well. See below code Snippets and let me know if you need more details.
Let me know where to look for.
MVC APP - Index.cshtml:
@{
ViewData["Title"] = "Home Page";
var asyncSettings = new Syncfusion.EJ2.Inputs.UploaderAsyncSettings { SaveUrl = "https://localhost:7108/api/UploadAzureStorage/Save" };
}
<div id="dropArea">
<span id="drop" class="droparea">Drop files here or<a id="browse" onclick="browseClick()"><u>Browse</u></a> </span>
<ejs-uploader id="UploadFiles" asyncSettings="@asyncSettings" autoUpload="false">
</ejs-uploader>
</div>
<script>function browseClick() {
document.getElementsByClassName('e-file-select-wrap')[0].querySelector('button').click(); return false;
}</script>
<style>
.e-file-select-wrap {
display: none;
}
#dropArea .e-upload {
border: 0;
margin-top: 15px;
}
#drop {
padding-left: 30%;
}
#dropArea {
min-height: 18px;
border: 1px dashed #c3c3cc;
padding-top: 15px;
margin: 20px auto;
width: 400px;
}
</style>
MVC APP - Program.cs:
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using UploadMVCAPP.Data;
using Azure.Storage.Blobs;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection") ?? throw new InvalidOperationException("Connection string 'DefaultConnection' not found.");
builder.Services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlite(connectionString));
builder.Services.AddDatabaseDeveloperPageExceptionFilter();
builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
.AddEntityFrameworkStores<ApplicationDbContext>();
builder.Services.AddControllersWithViews();
builder.Services.AddCors((options) => {
options.AddPolicy("AllowAnyOrigin",
builder => builder
.AllowAnyOrigin()
.AllowAnyHeader()
.AllowAnyMethod());
});
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseMigrationsEndPoint();
}
else
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
//Register Syncfusion license
Syncfusion.Licensing.SyncfusionLicenseProvider.RegisterLicense("LICENCE_KEY);
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
app.MapRazorPages();
app.Run();
API Upload Controller:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Mvc;
using Azure.Storage.Blobs;
using Azure.Storage.Blobs.Specialized;
using Azure.Storage.Blobs.Models;
// For more information on enabling MVC for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860
namespace UploadAPI.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class UploadAzureStorageController : ControllerBase
{
// GET: /<controller>/
private readonly string azureConnectionString;
public UploadAzureStorageController(IConfiguration configuration)
{
azureConnectionString = configuration.GetConnectionString("AzureConnectionString");
}
[HttpPost("[action]")]
public async Task<IActionResult> Save(IList<IFormFile> UploadFiles)
{
try
{
foreach (var files in UploadFiles)
{
// Azure connection string and container name passed as an argument to get the Blob reference of the container.
var container = new BlobContainerClient(azureConnectionString, "storagecontainer01");
// Method to create our container if it doesn’t exist.
var createResponse = await container.CreateIfNotExistsAsync();
// If container successfully created, then set public access type to Blob.
if (createResponse != null && createResponse.GetRawResponse().Status == 201)
await container.SetAccessPolicyAsync(Azure.Storage.Blobs.Models.PublicAccessType.Blob);
// Method to create a new Blob client.
var blob = container.GetBlobClient(files.FileName);
// If a blob with the same name exists, then we delete the Blob and its snapshots.
await blob.DeleteIfExistsAsync(Azure.Storage.Blobs.Models.DeleteSnapshotsOption.IncludeSnapshots);
// Create a file stream and use the UploadSync method to upload the Blob.
using (var fileStream = files.OpenReadStream())
{
await blob.UploadAsync(fileStream, new BlobHttpHeaders { ContentType = files.ContentType });
}
}
}
catch (Exception e)
{
Response.Clear();
Response.StatusCode = 204;
}
return Content("");
}
[HttpPost("[action]")]
public void Remove(IList<IFormFile> UploadFiles)
{
//try
//{
// var filename = hostingEnv.ContentRootPath + $@"\{UploadFiles[0].FileName}";
// if (System.IO.File.Exists(filename))
// {
// System.IO.File.Delete(filename);
// }
//}
//catch (Exception e)
//{
Response.Clear();
Response.StatusCode = 200;
Response.HttpContext.Features.Get<IHttpResponseFeature>().ReasonPhrase = "File removed successfully";
// Response.HttpContext.Features.Get<IHttpResponseFeature>().ReasonPhrase = e.Message;
// }
}
}
}
Class File:
using System;
namespace UploadAPI
{
public class UploadAzureStorage
{
public UploadAzureStorage()
{
}
}
}
API Program.CS:
namespace UploadAPI;
public class Program
{
public static void Main(string[] args)
{
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddCors((options) => {
options.AddPolicy("AllowAnyOrigin",
builder => builder
.AllowAnyOrigin()
.AllowAnyHeader()
.AllowAnyMethod());
});
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
}
}
API LaunchSettings.JSON:
{
"$schema": "http://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:24078",
"sslPort": 44374
}
},
"profiles": {
"http": {
"commandName": "Project",
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "http://localhost:5085",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"dotnetRunMessages": true
},
"https": {
"commandName": "Project",
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "https://localhost:7108;http://localhost:5085",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"dotnetRunMessages": true
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "swagger",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
Hi Nate,
Thank you for reaching out to Syncfusion Support!
We've thoroughly reviewed your query and conducted testing to address your concern regarding file uploads using the ejs-uploader control within your Core application. After examining the provided code snippets and conducting tests on our end, we couldn't reproduce the reported issue. The save method was triggered as expected without any errors.
To ensure smooth operation, please verify that the saveUrl path is correctly configured within your application. An incorrect path could prevent the save method from triggering, leading to failed uploads.
For your convenience, we have prepared a simple sample based on your requirements and have attached it below, along with a video illustrating the process:
Server: https://www.syncfusion.com/downloads/support/directtrac/general/ze/SyncfusionCoreUploader-910509046
Please review the sample and ensure that your application setup aligns with the demonstrated configuration. If the issue persists or if you require further assistance, feel free to reach out to us.