I built an ASP.NET Core 8.0 Web API which works fine in Google script and from a web site built from notepad. However when I am trying to communicate with it from an external site, it throws a CORS error
Access to fetch at ‘https://a.someting.edu/Newsletter/api/newsletter’ from origin ‘https://t4.something.edu’ has been blocked by CORS policy: Response to preflight request doesn’t pass access control check: It does not have HTTP ok status
My Program.cs
file:
var MyAllowSpecificOrigins = "_myAllowSpecificOrigins";
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(options =>
{
options.AddPolicy(name: MyAllowSpecificOrigins,
policy =>
{
policy.WithOrigins("https://t4.something.edu")
.AllowAnyHeader()
.AllowAnyMethod();
});
});
builder.Services.AddControllers();
// context
IConfiguration config = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.AddEnvironmentVariables()
.AddCommandLine(args)
.AddUserSecrets<Program>(true)
.Build();
builder.Services.AddDbContext<NewsletterContext>(option =>
{
option.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection"));
});
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddTransient<IApiKeyValidation, ApiKeyValidation>();
builder.Services.AddScoped<ApiKeyAuthFilter>();
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseCors(MyAllowSpecificOrigins);
app.UseAuthorization();
app.MapControllers();
app.Run();
Frontend HTML JavaScript Code
<script>
function send()
{
var url = 'https://a.something.edu/News/api/news';
var headers = {
'X-API-Key' : "something1234",
'Accept': "application/json",
'Content-Type': "application/json;charset=utf-8"
};
var data = {
"email" : document.getElementById("customerEmail").value
};
var payload = JSON.stringify(data);
var options = {
method: "POST",
headers: headers,
body: payload
};
try {
var response = fetch(url, options);
}catch(error) {
alert('Error is : ' + error);
}
alert('Response is - ' + response);
}
</script>
Included in my program.cs
file is cors middleware that I found on Microsoft learn cors, same issue and am not sure I set that up correctly as I still have to set the response header on the web server to Access-Control-Allow-Origin = *
. Which is verified by the web.config
file:
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
</customHeaders>
</httpProtocol>
</system.webServer>
Controller code
[Route("api/[controller]")]
[ApiController]
public class NewsletterController(NewsletterContext context) : ControllerBase
{
private readonly NewsletterContext _context = context;
[HttpPost]
public async Task<ActionResult<NewsletterItem>> PostNewsletterItem(NewsletterItem newsletterItem)
{
_context.Newsletter_Emails.Add(newsletterItem);
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
throw;
}
return Ok("The record has been saved correctly");
}
}
Model code
namespace NewsletterEmails.Models
{
public class NewsletterItem
{
[Key]
public required string Email { get; set; }
}
}
I tried to set the mode to no-cors, however that results in an unsupported media type error 415.