Now I use webApi and Angular apps such one project by default from VS. I want to separate it for two projects. I remove all from my StarUP file related with SPA. I run Angular part with command nmp run start and it run in 4200. I add ${environment.apiUrl}/api for my api request by this way
async loginUser(login: Login): Promise<any> {
return this.http.post(`${environment.apiUrl}/api/${environment.apiVersion}/userAuth/login`, login).toPromise();
And I see in the networking Request URL: https://localhost:44347/api/v1.0/userAuth/login
but I have cors error. My header look like this in network.
When I came back to one monolit project angular and webApi and ran it. In network my header look like this.
As you can see in first case I dont have fully header. How I can run my angular app separate from web api such a full single app? Thanks
If your are running as Asp.Net Core or 5+ application you have two ways of doing this:
1 - Enable CORS on your web api
This is ideal when you will serve your api and angular aplication from different servers in production.
In development your URLs will be:
Angular: https://localhost:4002 (you will use this one in your browser)
WebApi: https://localhost:44347
Statup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options =>
{
options.AddPolicy("Any",
builder =>
{
builder
.AllowAnyOrigin()
.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials();
});
});
options.AddPolicy("Production",
builder =>
{
builder.WithOrigins("https://your-angular-domain.com", "https://your-other-domain.com");
});
}
// Your other services
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseCors("Any"); // Allow any origin
}
else
{
app.UseCors("Production"); // Only allow specific origins
app.UseHsts();
app.UseHttpsRedirection();
}
// Your other middlewares....
}
2. Use Spa Middleware
This is ideal when you will serve your WebAPi and angular app from the same server in production.
In development your URLs will be:
Angular: https://localhost:4002
WebApi: https://localhost:44347 (you will use this one in your browser)
Statup.cs
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
// Your other middlewares....
app.UseSpa(spa =>
{
if (env.IsDevelopment()) // In production your angular app and web api will already be at the same server, or you should enable CORS
{
spa.UseProxyToSpaDevelopmentServer("http://localhost:4001");
}
});
}
Related
I created a brand new asp.net core web api app using default template with HTTPS configured.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseMvc();
}
When I run the app as console application, then https site (https://localhost:5001/api/values) is accessible and gave API result.
Now when I deployed this web API as Window Service, then site http site is accessible, but https site (https://localhost:5001/api/values) is not accessible? Whats the reason? Thanks!
After creating a certificate
dotnet dev-certs https -ep "localhost.pfx" -p Password1 --trust
I added below code,
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
// Configure the Url and ports to bind to
// This overrides calls to UseUrls and the ASPNETCORE_URLS environment variable, but will be
// overridden if you call UseIisIntegration() and host behind IIS/IIS Express
.UseKestrel(options =>
{
options.Listen(IPAddress.Loopback, 5000);
options.Listen(IPAddress.Loopback, 5001, listenOptions =>
{
listenOptions.UseHttps("localhost.pfx", "Password1");
});
})
And it's working even after hosting web api as window service.
I have read about this issue on some previous thread, however it is still not working, I have commented all console.log and still not working.
I am using Angular 6, may Web API is in .NET Core.
Thanks in Advance!
I finally found the answer after googling and trying different methods.
It may be a duplicated concern / issue, but I just want to share my experience doing a WebAPI using .Net Core.
I found out that my web app seems to disabled back and forward caching. (can be seen on Console F12 Dev Tools)
DOM7011: The code on this page disabled back and forward caching. For more information, see: http://go.microsoft.com/fwlink/?LinkID=291337
Add app.UseResponseCaching(); in Startup.cs
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
// Use Cross origin resource sharing
app.UseCors(
options => options.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
);
app.UseAuthentication();
//20180830
app.UseResponseCaching();
app.UseMvc();
}
Add services.AddResponseCaching(); in Startup.cs, ConfigureServices.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddResponseCaching();
...............
}
Finally add a response header on my Web API solves the issue.
[HttpGet("usraccessbk"), ResponseCache(Location = ResponseCacheLocation.None,
NoStore = true)]
public IActionResult GetWorkXXXXAccess(string user, string buXXXX) {
...........
}
I created an ASP.Net CORE web API project, with a single controller, and would now like to call it from a client (React) web app.
However, the call fails with "No 'Access-Control-Allow-Origin' header is present on the requested resource.".
When calling the same endpoint from Fiddler, the expected response headers are not present.
Thanks to ATerry, I have further insight: the headers are not present, because the React web app and the .Net Core web API are hosted on the same box. React populates the request Origin: header which is the same as the (API) box, thus the server (being really clever about it) does not add the Allow-... response headers. However, the React app rejects the response, because of the lack of those headers.
I'm using .Net Core v2.1 (latest as of this writing).
I built the code based on
https://learn.microsoft.com/en-us/aspnet/core/security/cors?view=aspnetcore-2.1
I checked these
https://weblog.west-wind.com/posts/2016/Sep/26/ASPNET-Core-and-CORS-Gotchas
CORS in .NET Core
How to enable CORS in ASP.NET Core
... but none of the suggestions worked.
Any ideas?
This is how I configure the .Net Core app (code changed from actual to try and allow anything):
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
// Enable CORS (Cross Origin Requests) so that the React app on a different URL can access it
// See https://learn.microsoft.com/en-us/aspnet/core/security/cors?view=aspnetcore-2.1
services.AddCors(options =>
{
options.AddPolicy(Global.CORS_ALLOW_ALL_POLICY_NAME, builder => builder
.AllowAnyOrigin()
.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials());
});
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)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseHsts();
}
app.UseCors(Global.CORS_ALLOW_ALL_POLICY_NAME);
app.UseHttpsRedirection();
app.UseMvc();
}
}
Having failed with just the above, I added the CORS attributes to the controller class and controller methods too:
[Route("api/[controller]")]
[ApiController]
[EnableCors(Global.CORS_ALLOW_ALL_POLICY_NAME)]
public class DealsController : ControllerBase
{
[...]
[HttpGet]
[EnableCors(Global.CORS_ALLOW_ALL_POLICY_NAME)]
public ActionResult<List<Deal>> GetAll()
{
return Store;
}
}
The response headers I get:
HTTP/1.1 200 OK
Transfer-Encoding: chunked
Content-Type: application/json; charset=utf-8
Server: Kestrel
X-Powered-By: ASP.NET
Date: Thu, 06 Sep 2018 12:23:27 GMT
The missing headers are:
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: http://localhost:3000
I believe it should work fine with LOCALHOST hosting as well, just do below changes and remove and any extra changes/configurations.
Replace this:
// Enable CORS (Cross Origin Requests) so that the React app on a different URL can access it
// See https://learn.microsoft.com/en-us/aspnet/core/security/cors?view=aspnetcore-2.1
services.AddCors(options =>
{
options.AddPolicy(Global.CORS_ALLOW_ALL_POLICY_NAME, builder => builder
.AllowAnyOrigin()
.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials());
});
with this:
services.AddCors();
and Replace this:
app.UseCors(Global.CORS_ALLOW_ALL_POLICY_NAME);
with this:
app.UseCors(x => x.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());
NOTE:
Even if your Web Api and React app are configured on LOCALHOST doesn't mean they are from same origin, it is because they are hosted on different port like react app is hosted on LOCALHOST:3000 and Web Api is hosted on LOCALHOST:5000. Web api will complaint if client(react app) is requesting from different port.
Above Web Api code will allow ANY ORIGIN and in production applications this is not safe so you need to allow specific ORIGIN to CORS access.
Managed to solve it by changing the URL used to access the server from a localhost based one to an IP address based one (localhost/api to 192.168.1.96/api).
It seems that part of the filtering that ATerry mentioned is based on host name: IIS doesn't send the Allow-... headers if hostname is localhost. Trouble is that React requires them.
You could try something like below as explained here: https://learn.microsoft.com/en-us/aspnet/core/security/cors?view=aspnetcore-2.2
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options =>
{
options.AddPolicy("AllowSpecificOrigin",
builder => builder.WithOrigins("http://example.com"));
});
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env,
ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
// Shows UseCors with named policy.
app.UseCors("AllowSpecificOrigin");
app.Run(async (context) =>
{
await context.Response.WriteAsync("Hello World!");
});
}
In your scenario it could be changed to something like the code below.
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options => options.AddPolicy(Global.CORS_ALLOW_ALL_POLICY_NAME,
builder =>
{
builder.AllowAnyOrigin()
.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials();
}));
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)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseHsts();
}
app.UseCors(Global.CORS_ALLOW_ALL_POLICY_NAME);
app.UseHttpsRedirection();
app.UseMvc();
}
}
This code might not look any different from yours however, there is a slight difference in the way the actions(what you call the builder) are defined. I hope that helps, good luck! :)
I got stuck with this same issue recently but doubted if mine was CORS related. So I went to deploy the app to my local IIS to check if that will get resolved somehow. Then checked the logs and found an issue pertaining to circular reference in data models - "Self referencing loop detected for property..". Applied an action in Startup.js to resolve the issue like so,
services.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1)
.AddJsonOptions(options =>
{
options.SerializerSettings.Formatting = Formatting.Indented;
// this line
options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
});
I want to add console logging if the application is started using the console. More information in the official documentation on Logging in ASP.NET 5. How can I tell if the application is running under the console?
public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory)
{
if (We are running under the console)
{
loggerFactory.AddConsole();
}
app.Run(async (context) =>
{
var logger = loggerFactory.CreateLogger("LoggingSample.Startup");
logger.LogInformation("Writing output.");
await context.Response.WriteAsync("Hello World!");
});
}
If you want to exclude logging when running Kestrel behind IIS/IIS Express, one option is to use the HTTP_PLATFORM_PORT environment variable added by the HttpPlatformHandler native module:
if (string.IsNullOrEmpty(Environment.GetEnvironmentVariable("HTTP_PLATFORM_PORT"))) {
// Only enable logging when running Kestrel or WebListener
// without IIS acting as a reverse-proxy.
}
Determining whether your app is hosted by WebListener can be done using the ServerFeatures property of the application builder:
if (app.ServerFeatures.Any(feature => feature.Key == typeof(WebListener))) {
// Add server-specific features here.
}
I have ASP.NET 5 web site (dnx451) hosted in Azure.
It works fine for an hour or so after the deployment and then CORS feature stop working. Other services like DI, Authorization and MVC are still functioning.
Here is Startup.cs code:
public void ConfigureServices(IServiceCollection services)
{
configureCors(services);
services.AddMvc(options =>
{
options.Filters.Add(new ErrorFilter());
});
}
private static void configureCors(IServiceCollection services)
{
services.AddCors();
services.ConfigureCors(x => x.AddPolicy("allowAll", p=>p.AllowAnyOrigin().
AllowAnyHeader().AllowAnyMethod()));
}
App configuration:
public void Configure(IApplicationBuilder app, IApplicationEnvironment env, ILoggerFactory loggerFactory)
{
app.UseMiddleware<StaticFileMiddleware>(new StaticFileOptions());
app.UseErrorPage();
// Add MVC to the request pipeline.
app.UseMvc();
app.UseCors("allowAll");
}
Local version has CORS all the time but Azure web has it only in the first 1-2 hours (depending on the usage). I guess CORS disappears when Azure restarts the app.
It is strange. Does anyone have the same problem?
Thanks to Henk, I was able to fix the problem:
I had both [EnableCors] attribute and app.UseCors() startup call. After removing UseCors, the problem disappeared.
However it is still strange why Cors is working temporarily when both options are in place.
Update:
As for https://github.com/aspnet/CORS/issues/36
You need not call services.AddCors() here as AddMvc internally already does that.