Any Suggestions for getting ASP.NET Core + React Running on Elastic Beanstalk - reactjs

I'm trying to get an ASP.NET Core with ReactJS application deployed to Amazon's Elastic Beanstalk. I've been using this tutorial to help me get started. I can deploy the tutorial (using the dotnet new web template) project just fine. However, when I publish a ASP.NET Core + React project (using dotnet new react template), I get the following exception when trying to access the application:
InvalidOperationException: The SPA default page middleware could not return the default page '/index.html' because it was not found, and no other middleware handled the request.
Your application is running in Production mode, so make sure it has been published, or that you have built your SPA manually. Alternatively you may wish to switch to the Development environment.
This only occurs when I try to access ClientApp/ React components. When I access an API endpoint, there is no problem.
Additionally, this does not occur when running locally. Running locally works fine.
To reproduce this error, I've executed the following:
dotnet new react -o test-react/
dotnet publish test-react/ -o site/
cd site/
zip ../deploy.zip *
Finally, I manually import deploy.zip into AWS Elastic Beanstalk.
This is the Startup.cs file for that project.
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.AddControllersWithViews();
// In production, the React files will be served from this directory
services.AddSpaStaticFiles(configuration =>
{
configuration.RootPath = "ClientApp/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
{
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.UseStaticFiles();
app.UseSpaStaticFiles();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller}/{action=Index}/{id?}");
});
app.UseSpa(spa =>
{
spa.Options.SourcePath = "ClientApp";
if (env.IsDevelopment())
{
spa.UseReactDevelopmentServer(npmScript: "start");
}
});
}
}
For reference, I am targeting .NET Core 3.1. Any ideas on how to solve this problem? I believe I've tried everything suggested on this GitHub issue. Any help would be greatly appreciated.
This question seems similar but is obviously for Angular and not React:
deploy Angular/Asp.Net Core 2.1 app to AWS: 500 error

It turns out that my deploy.zip package wasn't being created recursively so files in subdirectories were missing. Instead of doing,
zip ../deploy.zip *
I did,
zip -r ../deploy.zip *
which worked as intended. Silly me.

Related

ASP.NET Core - Serve both API and SPA React from different port

It is possible to serve both an API and a Single Page Application (SPA) React/Redux from different ports in ASP.NET Core. I found some post here ASP.NET Core - Serve both API and SPA from the same port that asks for serving from the same port, I would like to serve them on different ports because I would like to implement Azure B2C Authentication(so my spa can safely communicate with web api). I generated a boiler plate that includes react spa with .net web api but it is in one solution by default. Not sure if I should generate .net core web api and react app in a separate projects but when I run the application it serves both spa and webapi on the port that is configured in launchSettings.json for web api. In Startup.cs i have
services.AddSpaStaticFiles(configuration =>
{
configuration.RootPath = "ClientApp/build";
});
app.UseSpaStaticFiles();
app.UseSpa(spa =>
{
if (env.IsDevelopment())
{
spa.UseReactDevelopmentServer(npmScript: "start");
}
});
I tried to add "homepage": "https://localhost:3000",
to package.json of react.app I also tried to add spa.Options.DefaultPage = "https://localhost:3000"
I also tried spa.UseProxyToSpaDevelopmentServer("https://localhost:3000");
But none of that works. Is there something like a Nuget package or maybe some extra trick with configuration or should I give up on the boiler plate and create 2 independent projects(1 create-react-app and then generate a default web api project). Thanks
Different from the template for ASP.NET Core with React.js, React.js and Redux is using .net core3.1 so it doesn't have .env file. In that file you can set the running port of your project.
According to the MS document, I think React.js and Redux project is using middleware to compile the functions code first then put them to the static web page and display it. The following code do this part of job:
app.UseStaticFiles();
app.UseSpaStaticFiles();
app.UseSpa(spa =>
{
spa.Options.SourcePath = "ClientApp";
if (env.IsDevelopment())
{
spa.UseReactDevelopmentServer(npmScript: "start");
}
});
When you start the project in VS, you can see the port number in the browser, which is the running port of the whole project. So you think the API and SPA are running on the same port. From my perspective, API is using middleware to invoke SPA.
You can use command line code npm start in the ClientApp File to run the SPA as an independent project, it will run it on the default port 3000. Here is the screenshot of my test:

Deploy ASP.NET core 7 Web API with React front end

I wrote an ASP.NET Core 7 web API backend and standalone Javascript React front end. I can deploy the backend to IIS successfully and it works fine through postman. However when I try to deploy the react front end using the method described in this tutorial https://learn.microsoft.com/en-us/visualstudio/javascript/tutorial-asp-net-core-with-react?view=vs-2022
my visual studio just freaks out and crashes. I am trying to figure out how to deploy the front end manually without using the visual studio publish feature.
This is my project setup:
[1]: https://i.stack.imgur.com/cApdk.png
And this is the IIS side where the WEB API backend is currently published:
[2]: https://i.stack.imgur.com/GtJ9O.png
Do I need to create a separate site for the frontend or can I deploy it to the same site as the backend? How can I build the frontend and manually deploy to the IIS?
For the site to work properly, you should build the frontend part in production mode, i.e. use the command npm run build instead of npm run start.
And then move the resulting files to the wwwroot folder inside your NET7 project.
Additionally, you should add static files using the AddStaticFiles method.
https://learn.microsoft.com/en-us/aspnet/core/fundamentals/static-files?view=aspnetcore-7.0
Also remember to set the ports correctly, because you can have different ones in the development and production environment, you will do it in launchsetting.json
You just need to change your Program.cs file like below, the you could publish webapi project directly. Every step mentioned in the official document must be completed, and finally add the following code.
namespace WebApplication1
{
public class Program
{
public static void Main(string[] args)
{
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
else
{
app.UseDefaultFiles();
//app.UseStaticFiles();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
//app.MapControllers();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
// Add this line
endpoints.MapFallbackToFile("/index.html");
});
app.Run();
}
}
}
Test Result

How to troubleshoot local SQL connections in a Blazor App from Visual Studio 2019

Learning Visual Studio 2019, C#, and SQL on my local PC. Having trouble connecting to the local SQL databases and making sure that my app opens up in my local browser.
Now an app that has previously worked fine gives me a 404 error. I cannot figure out why this is happening. In general I would like to have a tool or some other checklists to see why the server is throwing the error.
Would love to have some advice on best ways to do this.
=================
I should have added code and better explanation initially.
I am rebuilding an app. Started with a fresh Blazor server app project, and started moving things over from the old app. I was eventually able to compile the new app and then launched it and originally got an SQL error.
Now I can get the app to launch a browser window (tried both Chrome and Edge) but nothing displays at all, it just looks like it is loading. There is nothing I can see in the console or in output. No errors. When I debug everything seems fine, the code never hangs on any line. Nothing ever errors out.
I can rebuild again but I want to figure out how to troubleshoot issues like this.
Startup.cs
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Wire_Desk.Data;
using Syncfusion.Blazor;
namespace Wire_Desk
{
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.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
services.AddServerSideBlazor();
services.AddSingleton<WeatherForecastService>();
services.AddSyncfusionBlazor();
}
// 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
{
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.UseStaticFiles();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapBlazorHub();
endpoints.MapFallbackToPage("/_Host");
});
}
}
}
Program.cs
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;
namespace Wire_Desk
{
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
}
I don't know what more code I should include. When I debug once I get through the program file and step into, there are no more code to step through, although this was also true with a small sample app.
I am stumped.

IdentityServer4 works only with HTTPS

I'm migrating from Identity Server 3 to 4.
I'm having trouble running Identity Server 4 without HTTPS in local development environment.
With HTTPS - everything works fine. Without it the user is not authenticated and just redirected
to the login page. The cookie is not set.
I know Identity Server 3 used to have the RequireSsl option that is now gone.
I've searched the docs for hours but came with nothing.
I'm on IdentityServer4 4.1.1 and AspNet Core 3.1
My Startup.cs looks like this:
public void ConfigureServices(IServiceCollection services)
{
services.AddIdentityServer()
.AddInMemoryClients(Clients.Get())
.AddInMemoryIdentityResources(Configs.Resources.GetIdentityResources())
.AddInMemoryApiResources(Configs.Resources.GetApiResources())
.AddInMemoryApiScopes(Configs.Resources.GetApiScopes())
.AddTestUsers(Users.Get())
..AddDeveloperSigningCredential();
services.AddControllersWithViews();
services.AddMvc(options => options.EnableEndpointRouting = false);
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseIdentityServer();
app.UseAuthorization();
app.UseEndpoints(endpoints => endpoints.MapControllers());
app.UseStaticFiles();
app.UseMvcWithDefaultRoute();
}
What am I missing?
I guess, you try it in Chrome. When you open dev console (F12) most likely you find the warnings that SameSite=None cookie must be secure.
If my above guess is right, there could two possible causes: you use customized CookieAuthenticationOptions where you explicitly set options.Cookie.SameSite = SameSiteMode.None (looking at your startup you don't), or the default one is not good for your configuration.
You can tweak it like below:
services.AddIdentityServer(options =>
{
options.Authentication.CookieSameSiteMode = SameSiteMode.Lax;
})
Will work on localhost, will block silent refresh for clients hosted beyond your IdSrv's root domain. So you have to choose whether you prefer Lax for production, or just for home playground (but in general None it not recommended anywhere).

Trying to serve CRA build folder statically in asp.net core 2

I created a basic web api, and added a react frontend using create-react-app. When in production I want to serve the build folder which gets created by running npm run build from create-react-app statically. Based on what I found on the docs here, I tried the following, but to no avail. I get a 404, and nothing on screen.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsProduction())
{
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(Directory.GetCurrentDirectory(), "client/build")),
RequestPath = "/static"
});
}
app.UseMvc();
}
Not sure where I am going wrong.

Resources