Blazor server, call api controller delete/{filename} to delete file. 404 response - api

I have an api that works in most functions, but not on my HttpDelete where I got 404 response.
[Route("/[controller]")]
[ApiController]
public class UploadController : ControllerBase
..
[HttpDelete("delete/{filename}")]
public IActionResult Delete(string filename)
{
try
{
var filePath = Path.Combine(grundPath, ulPath, filename);
if (System.IO.File.Exists(filePath))
{
System.IO.File.Delete(filePath);
return StatusCode(200);
}
}
catch (Exception ex)
{
return StatusCode(500, ex.Message);
}
return StatusCode(500);
}
My Blazor component :
..
#inject HttpClient Http
..
string url = $"delete/{filename}"
HttpResponseMessage response = await Http.DeleteAsync(url);
..
I have tried to set url = $"https://localhost:XXXX/delete..... but same result.
Filename are in form "picture.png"
StatusCode: 404, ReasonPhrase: 'Not Found', Version: 1.1, Content:
System.Net.Http.HttpConnectionResponse Content, Headers: { Set-Cookie:
x-ms-gateway-slice=estsfd; path=/; secure; httponly DATE...
I'm a newbie on api controller so I have no clue what I missed. Don't even know where to start google...
[EDIT : Added Swagger to project]
After analysed with Swagger, I got this in swagger :
[DELETE] /delete/{filename}
Added a filename and execute, got this requested url :
https://localhost:7285/delete/_eskilssk%C3%A4rmklipp.PNG
And the file are deleted. So far so good.
Change / added code to this :
string filename = WebUtility.UrlEncode(fil.Namn);
string baseUrl = $"https://localhost:7285/delete/{filename}";
await JsRuntime.ToastrSuccess("Info : " + baseUrl);
HttpResponseMessage response = await Http.DeleteAsync(baseUrl);
My Toastr gives me :
https://localhost:7285/delete/_eskilssk%C3%A4rmklipp.PNG
same as swagger...
But this in my output i Visual studio :
System.Net.Http.HttpClient.Default.LogicalHandler: Information: Start
processing HTTP request DELETE
https://localhost:7285/delete/_eskilsskärmklipp.PNG
System.Net.Http.HttpClient.Default.ClientHandler: Information: Sending
HTTP request DELETE
https://localhost:7285/delete/_eskilsskärmklipp.PNG
Could it be my encoding that's wrong?
My Program.cs, maybe wrong order?
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd"));
builder.Services.AddControllersWithViews()
.AddMicrosoftIdentityUI();
builder.Services.AddRazorPages();
builder.Services.AddAuthorization(options =>
{
options.FallbackPolicy = options.DefaultPolicy;
options.AddPolicy("Admin", policy => policy.RequireClaim("role", "Admin"));
});
builder.Services.AddAutoMapper(typeof(Program));
builder.Services.AddDbContext<ApplicationDbContext>(options =>
{
options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection"));
}, ServiceLifetime.Transient);
builder.Services.AddServerSideBlazor()
.AddMicrosoftIdentityConsentHandler();
builder.Services.AddScoped<>(); // Some repositories
..
builder.Services.AddScoped<DialogService>();
builder.Services.AddScoped<NotificationService>();
builder.Services.AddScoped<TooltipService>();
builder.Services.AddScoped<ContextMenuService>();
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/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();
}
app.UseDeveloperExceptionPage(); // Remove when publish!!!
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.MapRazorPages();
app.MapControllers();
app.MapDefaultControllerRoute();
app.MapBlazorHub();
app.MapFallbackToPage("/_Host");
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "Blazor API V1");
});
app.Run();
2022-11-10
Problem found, when I comment out // app.UseAuthentication and app.UseAuthorization I could reach the API from my component. It's a security problem and doesn't have anything to do with this original question.
Start a new question with more correct information.
Blazor server and API in same project, 404 not found when app.UserAuth is activate

In ASP.NET Core, the action's route is : [controller]/[action]. In your case :
/upload/delete/{filename}
The client need to call this url like :
..
#inject HttpClient Http
..
string url = $"upload/delete/{filename}"
HttpResponseMessage response = await Http.DeleteAsync(url);
..
If you want the action's url is delete/{filename}, then you can start the action route segment by /. ASP.NET Core MVC will ignore the controller route segment when the action route segment start by / like :
[HttpDelete("/delete/{filename}")]
public IActionResult Delete(string filename)

Related

.NET Core 6 Web Api Authentication/ Authorization not working

I have written a small .NET 6 minimal web api, which is heavily based on / copied from a tutorial I did. The tutorial worked as expected, but I have two problems in my version.
The first problem is with swagger. When I uncomment the line c.OperationFilter<SecurityRequirementsOperationFilter>(); in AddSwaggerGen() I get a swagger error in the browser "Failed to load API definition. Fetch error. response status is 500 https://localhost:7123/swagger/v1/swagger.json"
The second problem is (when the swagger line is commented out to get it to run) nothing is secured. Either from swagger or from the browser I can access all endpoints.
Here is my program.cs. It certainly looks like I have everything in the right place. Even so, I would have expected that if it was misconfigured, it would prevent me from accessing the endpoints.
using DataAccess.DbAccess;
using MyAuthAPI;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.Filters;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(
c => {
c.SwaggerDoc("v1", new OpenApiInfo { Title = "MyAPI", Version = "v1" });
c.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme {
Description = "Standard Authorization header using the Bearer scheme. Example: \"bearer {token}\"",
In = ParameterLocation.Header,
Name = "Authorization",
Type = SecuritySchemeType.ApiKey
});
// When this line is uncommented I get a swagger error- Failed to load api
// c.OperationFilter<SecurityRequirementsOperationFilter>();
});
builder.Services.AddSingleton<ISqlDataAccess, SqlDataAccess>();
builder.Services.AddSingleton<IPersonAuthData, PersonAuthData>();
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options => {
options.TokenValidationParameters = new TokenValidationParameters {
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(System.Text.Encoding.ASCII.GetBytes(builder.Configuration.GetSection("AppSettings:Token").Value)),
ValidateIssuer = false,
ValidateAudience = false
};
});
builder.Services.AddAuthorization();
var app = builder.Build();
// app.UseStatusCodePages();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseSwagger();
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "MyAPI v1"));
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.ConfigureRoutes();
app.Run();
The routes and db access etc all works fine, but here is the routes.cs file just in case.
using DataAccess.DTOs;
using Microsoft.AspNetCore.Authorization;
namespace MyAuthAPI;
[Authorize]
public static class Routes
{
public static void ConfigureRoutes(this WebApplication app)
{
app.MapGet("PersonAuths", GetPersonAuths);
app.MapGet("PersonAuths/{id}", GetPersonAuth);
app.MapPost("Login", Login);
}
private static async Task<IResult>GetPersonAuths(IPersonAuthData data)
{
try
{
return Results.Ok(await data.GetPersonAuths());
} catch(Exception ex)
{
return Results.Problem(ex.Message);
}
}
private static async Task<IResult> GetPersonAuth(int id, IPersonAuthData data)
{
try
{
var results = await data.GetPersonAuth(id);
if (results == null) return Results.NotFound();
return Results.Ok(results);
}
catch (Exception ex)
{
return Results.Problem(ex.Message);
}
}
[AllowAnonymous]
private static async Task<IResult> Login(LoginDTO loginDetails, IPersonAuthData data)
{
try
{
string jwt = await data.Login(loginDetails);
if (jwt != "")
{
return Results.Ok(jwt);
} else
{
return Results.Unauthorized();
}
}
catch (Exception ex)
{
return Results.Problem(ex.Message);
}
}
}
Thanks
Edit
The swagger issue looks like it may be due to Swashbuckle.AspNetCore.Filters not supporting minimal apis.
Swashbuckle.AspNetCore.Filters

Blazor Redirection on IIS swagger

I have a .NET 5 blazor WASM (with core server) solution.
I added swagger (nswag) like this:
public class Startup {
public void ConfigureServices(IServiceCollection services) {
services.AddControllersWithViews();
services.AddRazorPages();
services.AddAuthentication(NegotiateDefaults.AuthenticationScheme).AddNegotiate();
services.AddSwaggerDocument(); //SWAGGER
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) {
if(env.IsDevelopment()) {
app.UseDeveloperExceptionPage();
app.UseWebAssemblyDebugging();
}
else {
app.UseExceptionHandler("/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();
}
app.UseHttpsRedirection();
app.UseBlazorFrameworkFiles();
app.UseStaticFiles();
// Register the Swagger generator and the Swagger UI middlewares
app.UseOpenApi();
app.UseSwaggerUi3();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints => {
endpoints.MapRazorPages();
endpoints.MapControllers();
endpoints.MapFallbackToFile("index.html");
});
}
}
When I debug the appliation with IIS-Express and enter the address https://localhost:12234/swagger the swagger UI is displayed correctly.
But after deployment to IIS every address loads the blazor UI with "Sorry there is nothing at this address" instead of the swagger UI.
When I use an old IE (not able to run wasm) I get at least a title from swagger - so swagger is there on the server, but some "magic redirection" forces index.html to be loaded - no matter what I do.
By the way - I can call controller methods and a curl .../swagger/v1/swagger.json also works as expected.
How can I tell the app to accept URLs from the address line without redirection to index.html?
I use PWA and https in my project.
I found the solution.
There is a service-worker.published.js as a "subfile" in wwwroot/service-worker.js.
And there is code like this:
async function onFetch(event) {
let cachedResponse = null;
if (event.request.method === 'GET') {
// For all navigation requests, try to serve index.html from cache
// If you need some URLs to be server-rendered, edit the following check to exclude those URLs
const shouldServeIndexHtml = event.request.mode === 'navigate';
const request = shouldServeIndexHtml ? 'index.html' : event.request;
const cache = await caches.open(cacheName);
cachedResponse = await cache.match(request);
}
return cachedResponse || fetch(event.request);
}
After a little change everthing works fine now:
async function onFetch(event) {
let cachedResponse = null;
if (event.request.method === 'GET') {
// For all navigation requests, try to serve index.html from cache
// If you need some URLs to be server-rendered, edit the following check to exclude those URLs
const shouldServeIndexHtml = event.request.mode === 'navigate' && !event.request.url.includes('/swagger') && !event.request.url.includes('/api/');
const request = shouldServeIndexHtml ? 'index.html' : event.request;
const cache = await caches.open(cacheName);
cachedResponse = await cache.match(request);
}
return cachedResponse || fetch(event.request);
}
Adding two more conditions to shouldServeIndexHtml solved the problem.
const shouldServeIndexHtml = event.request.mode === 'navigate' && !event.request.url.includes('/swagger') && !event.request.url.includes('/api/');

ASP.NET Core 3.0 Redirect HTTP 4XX and 5XX requests to customized error pages while keeping the error code

I'm looking to redirect HTTP requests with 4XX or 5XX error code to a custom error page, while keeping the error code at the request level. I also want to redirect exceptions to a custom error page, with an error code 500.
For that I used in my Startup file
"app.UseStatusCodePagesWithReExecute("/error/{0}");
app.UseExceptionHandler("/error/500");"
associated with an Error controller.
The part about exceptions works well.
I also manage to redirect non-existent routes to my custom page while keeping the 404 error.
However, I can't redirect the following actions to my custom error pages:
return NotFound()
return BadRequest()
return StatusCode(404)
What would be the technical solution applied to accomplish this?
Here is the Configure function of my Startup file :
app.UseStatusCodePagesWithReExecute("/error/{0}");
app.UseExceptionHandler("/error/500");
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "Error-StatusCode-Route",
pattern: "error/{statusCode}",
defaults: new { controller = "Error", action = "InternalServerError" }
);
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
You could custom middleware to deal with it:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseStatusCodePagesWithReExecute("/error/{0}");
app.UseExceptionHandler("/error/500");
app.Use(async (context, next) =>
{
await next();
var code = context.Response.StatusCode;
var newPath = new PathString("/error/"+code);
var originalPath = context.Request.Path;
var originalQueryString = context.Request.QueryString;
context.Features.Set<IStatusCodeReExecuteFeature>(new StatusCodeReExecuteFeature()
{
OriginalPathBase = context.Request.PathBase.Value,
OriginalPath = originalPath.Value,
OriginalQueryString = originalQueryString.HasValue ? originalQueryString.Value : null,
});
// An endpoint may have already been set. Since we're going to re-invoke the middleware pipeline we need to reset
// the endpoint and route values to ensure things are re-calculated.
context.SetEndpoint(endpoint: null);
var routeValuesFeature = context.Features.Get<IRouteValuesFeature>();
routeValuesFeature?.RouteValues?.Clear();
context.Request.Path = newPath;
try
{
await next();
}
finally
{
context.Request.QueryString = originalQueryString;
context.Request.Path = originalPath;
context.Features.Set<IStatusCodeReExecuteFeature>(null);
}
});
app.UseHttpsRedirection();
app.UseStaticFiles();
//...
}
For your ErrorController:
public class ErrorController : Controller
{
// GET: /<controller>/
public IActionResult InternalServerError()
{
return View();
}
[Route("error/404")]
public IActionResult StatusCode404()
{
//redirect to the StatusCode404.cshtml
return View();
}
[Route("error/400")]
public IActionResult StatusCode400()
{
return View();
}
}
If you are using core3, then this is a known bug. This bug will be fixed in 3.1.
Here is a link to the issue: https://github.com/aspnet/AspNetCore/issues/13715
For now there is a workaround. You can add this code right after you call app.UseStatusCodePagesWithReExecute("/error/{0}");
app.Use((context, next) =>
{
context.SetEndpoint(null);
return next();
});
This will render your custom pages when you return NotFound or BadRequest from your controller action.

ASP.net-core 3.0 - Is it possible to return custom error page when user is not in a policy?

I'm creating an intranet website and I'm having some trouble with the authentication part. I would like to limit the access for a controller to users in a specific Active Directory Roles. If the user is not in the specified Roles, then it should redirect him to a custom error page.
Windows authentication is enabled. I've tried the following solutions :
I created a custom policy in my ConfigureServices method inside my Startup.cs :
...
services.AddAuthorization(options =>
{
options.AddPolicy("ADRoleOnly", policy =>
{
policy.RequireAuthenticatedUser();
policy.RequireRole(Configuration["SecuritySettings:ADGroup"], Configuration["SecuritySettings:AdminGroup"]);
});
});
services.AddAuthentication(IISDefaults.AuthenticationScheme);
....
with inside my appsettings.json my active directory groups (not the one i'm really using of course) :
"SecuritySettings": {
"ADGroup": "MyDomain\\MyADGroup",
"AdminGroup": "MyDomain\\MyAdminGroup"
}}
and inside my Configure method :
...
app.UseAuthorization();
app.UseAuthentication();
app.UseStatusCodePagesWithReExecute("/Home/ErrorCode/{0}");
...
I have the following controller :
[Area("CRUD")]
[Authorize(Policy = "ADRoleOnly")]
public class MyController : Controller
I have a HomeController with the following method :
[AllowAnonymous]
public IActionResult ErrorCode(string id)
{
return View();
}
but when I debug my site, this method is never reached.
If I'm a user inside one of the specified roles of my policy, it's all working as expected.
But if I'm not a member of the roles, I'm redirected to the default navigator page.
I would like to redirect to a custom error page. I thought that was the purpose of
app.UseStatusCodePagesWithReExecute("/Home/ErrorCode/{0}");
It will generate a 403 statuscode when the policy fails,app.UseStatusCodePagesWithReExecute does not detect 403:
UseStatusCodePagesWithReExecute is not working for forbidden (403)
You could write a custom middleware to deal with it :
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
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();
}
app.Use(async (context, next) =>
{
await next();
if (context.Response.StatusCode == 403)
{
var newPath = new PathString("/Home/ErrorCode/403");
var originalPath = context.Request.Path;
var originalQueryString = context.Request.QueryString;
context.Features.Set<IStatusCodeReExecuteFeature>(new StatusCodeReExecuteFeature()
{
OriginalPathBase = context.Request.PathBase.Value,
OriginalPath = originalPath.Value,
OriginalQueryString = originalQueryString.HasValue ? originalQueryString.Value : null,
});
// An endpoint may have already been set. Since we're going to re-invoke the middleware pipeline we need to reset
// the endpoint and route values to ensure things are re-calculated.
context.SetEndpoint(endpoint: null);
var routeValuesFeature = context.Features.Get<IRouteValuesFeature>();
routeValuesFeature?.RouteValues?.Clear();
context.Request.Path = newPath;
try
{
await next();
}
finally
{
context.Request.QueryString = originalQueryString;
context.Request.Path = originalPath;
context.Features.Set<IStatusCodeReExecuteFeature>(null);
}
// which policy failed? need to inform consumer which requirement was not met
//await next();
}
});
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
}

CORS error with Aurelia calling .NET core API 2.0

I am getting a CORS error and I don't know how to fix it. I have an Aurelia app, calling a .NET core 2.0 API using aurelia-fetch-client. I am getting the following error:
Failed to load http://localhost:58289/api/info: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8080' is therefore not allowed access. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
TypeError: Failed to fetch
at applyInterceptors (webpack-internal:///./node_modules/aurelia-fetch-client/dist/native-modules/aurelia-fetch-client.js:428:14)
at processResponse (webpack-internal:///./node_modules/aurelia-fetch-client/dist/native-modules/aurelia-fetch-client.js:411:10)
at eval (webpack-internal:///./node_modules/aurelia-fetch-client/dist/native-modules/aurelia-fetch-client.js:299:14)
From previous event:
at HttpClient.eval (webpack-internal:///./node_modules/aurelia-fetch-client/dist/native-modules/aurelia-fetch-client.js:287:61)
at HttpClient.fetch (webpack-internal:///./node_modules/aurelia-fetch-client/dist/native-modules/aurelia-fetch-client.js:273:21)
at App.callApi (webpack-internal:///app:42:25)
at CallScope.evaluate (webpack-internal:///./node_modules/aurelia-binding/dist/native-modules/aurelia-binding.js:1578:19)
at Listener.callSource (webpack-internal:///./node_modules/aurelia-binding/dist/native-modules/aurelia-binding.js:5279:40)
at Listener.handleEvent (webpack-internal:///./node_modules/aurelia-binding/dist/native-modules/aurelia-binding.js:5288:10)
at HTMLDocument.handleDelegatedEvent (webpack-internal:///./node_modules/aurelia-binding/dist/native-modules/aurelia-binding.js:3363:20)
Please find my code below.
aurelia-fetch-client configuration:
const http = new HttpClient().configure(config => {
config
.withBaseUrl(environment.apiBaseUrl)
.withDefaults({
headers: {
'Content-Type': 'application/json'
}
})
.withInterceptor({
request(request: Request) {
var token = localStorage.getItem('access_token')
request.headers.append('Authorization', 'Bearer ' + token)
return request;
},
responseError(error){
return error;
}
});
});
aurelia.container.registerInstance(HttpClient, http);
Call the API:
callApi(){
this.httpClient.fetch("/info")
.then(response => console.log(response));
}
API startup configuration:
public void ConfigureServices(IServiceCollection services)
{
string domain = $"https://{Configuration["Auth0:Domain"]}/";
var allowedCors = Configuration["CorsSite"];
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(options =>
{
options.Authority = domain;
options.Audience = Configuration["Auth0:ApiIdentifier"];
});
services.AddCors(options => options.AddPolicy("AllowSpecificOrigin", `builder => {`
builder.AllowAnyOrigin().AllowAnyMethod(); }));
services.AddMvc();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseCors("AllowSpecificOrigin");
app.UseAuthentication();
app.UseMvc();
}
Controller:
[Produces("application/json")]
[Route("api")]
public class InfoController : Controller
{
// GET api/values
[HttpGet]
[Route("Info")]
public IActionResult Get()
{
return Ok("Api V1.0");
}
[Route("authorizedInfo")]
[Authorize]
[HttpGet]
public IActionResult GetAuthorized()
{
return Ok("Authorized Api V1.0");
}
}
Please ignore the authorisation bit for now. I am only trying to hit the unauthorised API endpoint in localhost, but I am stuck. How can I fix my problem?
To do this start with registering CORS functionality in ConfigureServices() of Startup.cs:
public void ConfigureServices(IServiceCollection services)
{
// Add service and create Policy with options
services.AddCors(options =>
{
options.AddPolicy("CorsPolicy",
builder => builder.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials() );
});
services.AddMvc();
}
The AddCors() call above adds the CORS features to ASP.NET and creates a custom policy that can be reused in the application by name. There are other ways to do essentially the same thing by explicitly adding a policy builder in the configuration step but to me this seems cleanest - define one or more policies up front and then apply it.
Once the policy has been defined it can be applied.
You can apply the policy globally to every request in the application by call app.useCors() in the Configure() method of Startup:
public void Configure(IApplicationBuilder app)
{
// ...
// global policy - assign here or on each controller
app.UseCors("CorsPolicy");
// ...
// IMPORTANT: Make sure UseCors() is called BEFORE this
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
or you can apply the policy to individual controllers:
[EnableCors("CorsPolicy")]
[ApiExceptionFilter]
public class AlbumViewerApiController : Controller
Thank You
The answer in the following link fixed my issue.
Web API 2 CORS IIS Express Debug and No Access-Control-Allow-Origin header
It appears that if there is no origin header in the request the server will not respond with the corresponding Access-Control-Allow-Origin response. Also with aurelia-fetch-client defaults I would have expected to have the origin header added by default.