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");
}
});
}
I have tried a couple of different ways to set up this project and each one fails. Here are my issues.
Using command prompts to creating these projects as directed in this article has one major flaw, if you generate these, then open it up in VS 2019, you can run it out of the box, no issues. The SECOND you add a file, it will prompted you to save a solution file, after that, the entire solution crashes and you can no longer launch it.... so this option seems hosed.
I tried to create a .net core 3 application with VS 2019, making it a WebAPI application. After that, I went into the root directory and by command prompt wrote: npx create-react-app client which appeared to create the project correctly. After that, I went to the startup.cs file added the spa items needed for it to run (added NuGet package Microsoft.AspNetCore.SpaServices.Extensions)
Here is my startup.cs code:
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.AddMvc().AddNewtonsoftJson();
services.AddSpaStaticFiles(configuration =>
{
configuration.RootPath = "client/build";
});
}
// 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();
}
else
{
// 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.UseRouting(routes =>
{
routes.MapControllers();
});
app.UseSpa(spa =>
{
spa.Options.SourcePath = "client";
if (env.IsDevelopment())
{
spa.UseReactDevelopmentServer(npmScript: "start");
}
});
app.UseAuthorization();
}
}
When I run this, the line where spa.UserReactDevelopmentServer(npmScript: "start") keeps throwing an error. The error is:
{"Method not found: 'Void Microsoft.Extensions.Logging.Console.ConsoleLogger..ctor(System.String, System.Func`3, Boolean)'."}
Does anyone have a clue as to creating a .NET Core 3.0 WebAPI with React front-end (not the type script version) that will both run the React when you hit play (green continue button in VS 2019) AND still have the API part work when calling it. It shouldn't be this hard for God Sake!!
I had the same issue.
Changing version of reference for "Microsoft.AspNetCore.SpaServices.Extensions" in project .csproj to "3.0.0-preview8.19405.4" worked for me.
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 had the following error in package manager console when Add-Migration
Value cannot be null. Parameter name: connectionString
This is my startup:
namespace MyProject
{
public class Startup
{
public IConfiguration Configuration { get; set; }
public Startup(IConfiguration config)
{
Configuration = config;
}
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContextPool<AppDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddTransient<IDevRepo, DevRepo>();
services.AddMvc();
services.AddMemoryCache();
services.AddSession();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseStatusCodePages();
app.UseStaticFiles();
app.UseMvcWithDefaultRoute();
app.Run(async (context) =>
{
await context.Response.WriteAsync(Configuration["Message"]);
});
}
}
}
program class:
public class Program
{
public static void Main(string[] args)
{
BuildWebHost(args).Run();
}
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((context, builder) => builder.SetBasePath(context.HostingEnvironment.ContentRootPath)
.AddJsonFile("appsettings.json")
.Build())
.UseStartup<Startup>()
.Build();
}
appsettings.json:
{
"Message": "Hello World",
"ConnectionStrings": {
"DefaultConnection": "Server=(localdb)\\MSSQLLocalDB;Database=NotMyFault;Trusted_Connection=True;MultipleActiveResultSets=true"
}
}
Interestingly if I run the app, it displays "Hello World", but when add migration it cannot find connectionString. Can someone please shed some lights here? Thanks.
This problem occurred when the connection string can't be found.
Probably you have the following code in Startup class:
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<BenchmarkContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("yourConnectionString name from appsettings.json")));
}
These methods solve your problem:
1- Instead of Configuration.GetConnectionString("yourConnectionString name from appsettings.json(in develop mode: 'appsettings.Development.json')") just put your connectionstring.
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<BenchmarkContext>(options =>
options.UseSqlServer("Data Source=.;Initial Catalog=Benchmark;Persist Security Info=True;User ID=****;Password=****"));
}
2- If you are going to use the Configuration file add these codes to Startup class:
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration;
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<BenchmarkContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("TestConnection")));
}
Appsettings.json file(in develop mode: 'appsettings.Development.json'):
{
"ConnectionStrings": {
"TestConnection": "Data Source=.;Initial Catalog=Benchmark;Persist Security Info=True;User ID=****;Password=****"
}
}
After that execute 'add-migration name' command in Package Manager Console
I had the same issue, but my solution was a lot simpler. All I did was to change the order of the appsettings.json from:
{
"Message": "Hello World",
"ConnectionStrings": {
"DefaultConnection": "Server=(localdb)\\MSSQLLocalDB;Database=NotMyFault;Trusted_Connection=True;MultipleActiveResultSets=true"
}
}
to:
{
"ConnectionStrings": {
"DefaultConnection": "Server=(localdb)\\MSSQLLocalDB;Database=NotMyFault;Trusted_Connection=True;MultipleActiveResultSets=true"
},
"Message": "Hello World"
}
I have a suspicion that there is a sequence/order of parameters in the appsettings.json file.
I had such issue when load tesing the service (I recommend it to all) and had ~3/1000 requests with errors,
so I changed
services.AddDbContextPool<AppDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
to
string connectionString = Configuration.GetConnectionString("DefaultConnection");
services.AddDbContextPool<AppDbContext>(options =>
options.UseSqlServer(connectionString));
So it reads connections string 1 time and doesn't use Configuration on every request. And now 100% requests are successful.
But it seems to be a bug in .Net Core
I found my own problem.
I have an AppDbContextFactory class which inherits IDesignTimeDbContextFactory. Deleting this class resolves this issue.
I had the same problem, because I was using the default value in Startup.cs.
I just edited Configuration property from:
public IConfiguration Configuration { get; }
to:
public IConfiguration Configuration;
and it worked!
If someone say why would be appreciated.
I had had a similar issue because of the following reasons:
appsettings.json was not included in the project
I was running the project from the path which did not contain appsettings.json
I had the same error and resolved it by moving "ConnectionStrings" to be the first variable in the appsettings.json file.
Probably, the issue is with your DotNetCliToolReference from the csproj file. If you migrate the project from an older version of asp.net core, the DotNetCliToolReference is not automatically updated.
Update the yourproject.csproj file to use the 2.0.0 version of the CLI as shown in the snippet bellow:
<ItemGroup>
...
<DotNetCliToolReference
Include="Microsoft.EntityFrameworkCore.Tools.DotNet"
Version="2.0.0" />
</ItemGroup>
Rerun, from the project folder, the dotnet command with -v switch to see results
dotnet ef database update -v
Also, recheck your Microsoft.EntityFrameworkCore nuget packages to reference the 2.0.0 version. Remove or update older EF packages. The minimum are:
Microsoft.EntityFrameworkCore.SqlServer
Microsoft.EntityFrameworkCore.Design
both 2.0.0 at this moment.
I had the same problem and what it is the I had to make sure that the name of the connection matches:
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddDbContext<MyContext>(options => options.UseSqlServer(Configuration["ConnectionStrings:DefaultConnection"]));
which ****ConnectionStrings:DefaultConnection*** it was where I had the whole problem.
Make sure that is the same in Startup.cs and appsettings.json(appsettings.Development.json in Vs 2019)
After I fixed this, everything was fine.
I had a similar issue. I had a typo in my appsettings.json. Changing ConnectionsStrings to ConnectionStrings did it for me!
I have solved my issue by setting right base path. The problem is the migrations or anything else from different packages uses wrong path to the appsetting.json file. Not sure if it's an official issue.
I have just changed my Startup.cs as follows:
public Startup(IHostingEnvironment env)
{
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true)
.AddEnvironmentVariables();
Configuration = builder.Build();
}
After that you just need to copy your appsettings.json to the right place if it's missing there.
This worked flawlessly for me:
public IConfiguration Configuration;
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationDbContext.ApplicationDbContext>(options =>
//options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
options.UseSqlServer("Server=serverAddress; Database=dbName; user=username; password=pswd"));
}
The commented part is just as reference where to replace.
Another scenario can be where you set the configuration. set the connection string in appsettings.json instead of appsettings.Development.json
I had a similar problem when I specified the ".UseContentRoot" as the current process path.
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseUrls("http://*:3001")
.UseStartup<Startup>()
.UseContentRoot(Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName));
thus when running Add-Migration the process path is different from the project bin path therefore the process can't find the appsettings.json file.
when I removed the ".UseContentRoot" line the migration was successful
I'm stupid and I had typo
{
"Conn'ce'tionStrings": {
"DefaultConnection": "Data source=datingapp.db"
},
changed it to
{
"ConnectionStrings": {
"DefaultConnection": "Data source=datingapp.db"
},
I had a similar problem after trying to use new created project for ASP.NET Core 2.0 Web Api. As far as I found, the cause of the problem was that application settings specified for development environment were not added. I fixed it by updating startup file to the following:
public Startup(IHostingEnvironment env)
{
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
.AddEnvironmentVariables();
this.Configuration = builder.Build();
}
In my case program class looks like the following:
public class Program
{
public static void Main(string[] args)
{
BuildWebHost(args).Run();
}
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.Build();
}
My problem was when I was trying to run App.dll within netcoreapp2.1 folder, but the right folder is netcoreapp2.1\publish\
If you have previously renamed your connection string in appsettings file and you have omitted to rename it in DesignTimeDbContextFactory class (if you have it in your project) and that is checked by Entity framework, then you may run in this issue.
If you are using an IDesignTimeDbContextFactory, you will need to add a default constructor to it with no parameters. Try something like this:
public DbContextFactory()
{
IConfigurationRoot configuration = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddEnvironmentVariables()
.AddJsonFile("appsettings.json", false, true)
.Build();
_connectionString = configuration.GetConnectionString("ConnectionStringName");
}
For me it was that I had appSettings.json instead of appsettings.json for some reason (not quite sure if VS did that with a newly created project or I had renamed it to that). Once I changed the name, it worked fine.
I figured I would add what it was for me. I had followed a popular tutorial to add appsettings.json and dependency injection to a console application. I did not realize in the setup that it referenced the current directory and was using that to set the base path of the configuration builder. It worked fine when I was running locally, but as soon as I tried to deploy and have a SQL scheduled job run the command it was taking the directory where the command was being entered, not where the DLL was so it wasn't finding my appsettings.json file. I simply removed the lines that dealt with getting the current directory and setting that as the base path and it works fine. It seems like it defaults to the same folder as the DLL.
I had this problem due to a difference in connectionstring of appsetting.json file, and the GetConnectionString(connectionstrings) parameter in startup.cs. Once I removed extra s in startup.cs, the problem disappeared.
Check if ASPNETCORE_ENVIRONMENT variable is set up on the server correctly. Depending on that environment it may be taking appsettings.json instead of appsettings.Staging.json or appsettings.Production.json.
In my case i was using configuration["DbContext"]
services.AddDbContext<AstroBhaskarDbContext>(option =>
{
option.UseSqlServer(configuration["DbContext"]);
});
then i replaced configuration["DbContext"] to configuration.GetConnectionString("DbContext") as below
services.AddDbContext<AstroBhaskarDbContext>(option =>
{
option.UseSqlServer(configuration.GetConnectionString("DbContext"));
});