I have CORS Policy blocking error only while uploading file to server using AspNet Core API 3.1. Adding cors policy to startup in different ways and using custom middleware not solved my problem.
Startup:
// ConfigureServices
services.AddCors(options =>
{
options.AddPolicy("EnableSVCCors", builder =>
{
builder
.AllowAnyOrigin()
.AllowAnyHeader()
.AllowAnyMethod()
.Build();
});
});
// Configure
app.UseCors("EnableSVCCors");
All API methods working fine by calling from react client web site but while trying to upload image I have following error:
Access to XMLHttpRequest at 'http://172.16.1.34:1980/api/accounts/uploadAvatar' from origin 'http://172.16.1.35:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
I also try to change cors policy as below but not working:
services.AddCors(options =>
{
options.AddPolicy("EnableSVCCors", builder =>
{
builder
.WithOrigins("http://172.16.1.35:3000")
.AllowAnyHeader()
.AllowAnyMethod()
.Build();
});
});
Note: Calling http://172.16.1.34:1980/api/accounts/uploadAvatar using PostMan and sending base64 string as image is working fine! So there is no problem with access limits on folder where image going to be saved.
I also tried to add custom middleware as below but not working as yet:
public class CorsMiddleWare
{
private readonly RequestDelegate _next;
public CorsMiddleWare(RequestDelegate next)
{
_next = next;
}
public Task Invoke(HttpContext httpContext)
{
httpContext.Response.Headers.Add("Access-Control-Allow-Origin", "http://172.16.1.35:3000");
return _next(httpContext);
}
}
public static class CorsMiddlewareExtensions
{
public static IApplicationBuilder UseCorsMiddleware(this IApplicationBuilder builder)
{
return builder.UseMiddleware<CorsMiddleWare>();
}
}
Any one have any idea please?
EDIT : Return headers in console is as below
Request URL: http://172.16.1.34:1980/api/accounts/uploadAvatar Referrer Policy: no-referrer-when-downgrade Date: Tue, 14 Apr 2020 03:50:49 GMT Server: Microsoft-IIS/10.0 Transfer-Encoding: chunked X-Powered-By: ASP.NET Accept: application/json, text/plain, / Accept-Encoding: gzip, deflate Accept-Language: en-US,en;q=0.9 Authorization: Bearer eyJhb..... Connection: keep-alive Content-Length: 22869 Content-Type: application/json;charset=UTF-8 Host: 172.16.1.34:1980 Origin: http://172.16.1.35:3000 Referer: http://172.16.1.35:3000/create-profile User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36 {fileName: "avatar", mediaType: "image/png",…} fileName: "avatar" mediaType: "image/png" buffer: "iVBORw0KGgoAAAANSUhEUgAAAPoAAAD6CAYAAACI7Fo9AAAgAE
The problem solved by changing the type of object is sending as image file to HttpFile contains in MultipartDataMediaFormatter.V2 https://github.com/iLexDev/ASP.NET-WebApi-MultipartDataMediaFormatter
Upload View Model :
public class ProfileAvatarUploadViewModel
{
public HttpFile Image { get; set; }
}
Api Controller :
[HttpPost("UploadAvatar")]
[Authorize(AuthenticationSchemes = "Bearer", Roles = "Manager,Admin,User")]
public async Task<IActionResult> UploadAvatar([FromBody] ProfileAvatarUploadViewModel model)
{
var userId = User.FindFirst(ClaimTypes.Name)?.Value;
if (userId == null || !await _userAccountRepository.IsExists(int.Parse(userId)))
{
return Forbid();
}
var avatarToUpload = new ProfileAvatarUploadModel
{
UserAccountId = int.Parse(userId),
UploadedImage = model.Image
};
var uploadedAvatar = await _profileAvatarRepository.UploadAvatar(avatarToUpload);
return Ok(uploadedAvatar);
}
Repository :
public async Task<ProfileAvatarViewModel> UploadAvatar(ProfileAvatarUploadModel model)
{
var (key, value) = SVCardTools.SaveImage(model.UploadedImage);
if (key.Equals(false))
{
throw new Exception(value);
}
var newAvatar = new ProfileAvatar
{
UserAccountId = model.UserAccountId,
AvatarUrl = value,
IsActive = false,
IsPublic = false
};
_context.Entry(newAvatar).State = EntityState.Added;
await _context.SaveChangesAsync();
return ProfileAvatarViewModel.Set(newAvatar);
}
SaveImage function :
public static KeyValuePair<bool, string> SaveImage(HttpFile file)
{
var bytes = file.Buffer;
try
{
var fileExt = file.MediaType.Split('/')[1];
switch (fileExt.ToLower())
{
case "png":
fileExt = ".png";
break;
case "jpg":
fileExt = ".jpg";
break;
default:
return new KeyValuePair<bool, string>(false, "Message");
}
var sb = new StringBuilder();
sb.Append(DateTime.Now.Ticks);
var saveFilePath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot\\avatars",
$"{sb}{fileExt}");
var saveDbPath = $"{sb}{fileExt}";
if (bytes.Length > 0)
{
using (var stream = new FileStream(saveFilePath, FileMode.Create))
{
stream.Write(bytes, 0, bytes.Length);
}
}
return new KeyValuePair<bool, string>(true, saveDbPath);
}
catch (Exception e)
{
var message = e.Message;
return new KeyValuePair<bool, string>(false, message);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With