Ryan can fly
Ryan can fly

Reputation: 123

.net 7 CORS error on posting file upload to controller

The problem as been solved:

I found a problem and finally I fixed it! That's because I dont set permissions for www-data user in ubuntu. just run "sudo chown -R www-data /var/www/abc.vn/wwwroot/uploads" and with the upload api I wrote above, it works!


I got a CORS error when trying to upload FormData to Controller. But the problem is it could run very well on localhost but on the server is no.

Access to fetch at 'http://api.abc.vn/OnPostUpload' from origin 'http://central.abc.vn' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

My localhost: Windows and IIS

My Server: Ubuntu 22 and Nginx

This is the javascript using fetch to send data:

let formData = new FormData();
formData.append('FileDetails', e.target.files[0]);
formData.append('FileName', e.target.files[0].name);
formData.append('TenantId', localStorage.getItem('TenantId'));
fetch(API_URL + 'OnPostUpload',
{
    method: 'POST',
    headers: {
        'Accept': 'application/json',
        'TenantId': localStorage.getItem('TenantId'),
        'Token': localStorage.getItem("Token")
    },
    body: formData
})

This is my Upload api:

        [HttpPost]
        [Route("/OnPostUpload")]
        public async Task<IActionResult> OnPostUploadAsync([FromForm] FileUploadModel data)
        {
            if (data == null)
            {
                return new JsonResult(false);
            }

            if (data != null)
            {
                string path = Path.GetFullPath(Path.Combine(Environment.CurrentDirectory, @"wwwroot/uploads/" + data.TenantId + "/"));
                if (!Directory.Exists(path))
                {
                    Directory.CreateDirectory(path);
                }

                var fileName = Guid.NewGuid().ToString("N") + Path.GetExtension(data.FileName);
                var absolutePath = Path.Combine(path, fileName);

                var appfile = await _repository.AddAsync(new AppFile()
                {
                    FileName = data.FileName,
                    Path = absolutePath,
                    TenantId = data.TenantId,
                });
                await _repository.SaveChangesAsync();

                using (var fileStream = new FileStream(absolutePath, FileMode.Create))
                {
                    await data.FileDetails.CopyToAsync(fileStream);
                }
                return new JsonResult(new { Path = "uploads/" + data.TenantId + "/" + fileName, AppFileId = appfile.Id });
            }
            return new JsonResult(false);
        }

FileUploadModel.cs

public class FileUploadModel
    {
        public IFormFile FileDetails { get; set; }
        public string FileName { get; set; }
        public string TenantId { get; set; }
    }

What I have tried?

And thanks for spending your time to read my post. Hope to hear your solution

Upvotes: 0

Views: 423

Answers (1)

vchy
vchy

Reputation: 36

I didn't see the complete cross-domain configuration, if I guess well, maybe you are missing app.UseCors(DefaultCorsPolicyName)

Sample code

const string DefaultCorsPolicyName = "ApiCORS";

builder.Services.AddCors(options =>
{
    options.AddPolicy(DefaultCorsPolicyName,
    builder =>
    {
        builder
        .WithOrigins("https://localhost:44460", "http://central.abc.vn", "http://demo.abc.vn")
        .AllowAnyHeader()
        .AllowAnyMethod()
        .AllowCredentials();
    });
});

.....

// This should be above the UseStaticFiles();
// Typically, UseStaticFiles is called before UseCors. Apps that use JavaScript to retrieve static files cross site must call UseCors before UseStaticFiles.
app.UseCors(DefaultCorsPolicyName);

If you want to go deeper, read the Microsoft docs

Upvotes: 0

Related Questions