Nancyfx Views not found when debugging ASP.NET Core 1.0 application - nancy

Am having problems resolving Nancyfx views with Asp.net Core 1.0 in debug mode. This is because folders like wwwroot are not output in the bin folder. I've googled but have not found anyways of sending folders to bin/Debug. However when I published and run the app the views are resolved fine. This is because the project.json I can configure for folders to be outputted. I know I can customize the ViewLocations but if I do so for it to work in debug then it will not work when published.

You have couple of options here:
Setup the ContentRoot. The following code uses the project directory as the location for views.
public class Program
{
public static void Main(string[] args)
{
var host = new WebHostBuilder()
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.UseStartup<Startup>()
.Build();
host.Run();
}
}
You can use the copyToOutput node in project.json for this purpose.
Example:
"buildOptions": {
"copyToOutput": {
"include": [
"Areas",
"Views",
"wwwroot",
"config.json",
"web.config"
]
}

Related

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

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

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.

Spring-boot: add application to tomcat server

I have a back-end which is build on spring-boot and then some custom code from my school built upon that.
The front-end is pure angular application which I serve from a different server trough a gulp serve.
They're only connected by REST calls.
There's already an authentication module running on the backend and to now I need to serve this angular application from the same tomcat server the back-end is running on so it can also use this authentication module.
I've found this about multiple connectors so I copied it as following class to set up multiple connectors:
#ConfigurationProperties
public class TomcatConfiguration {
#Bean
public EmbeddedServletContainerFactory servletContainer() {
TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory();
//tomcat.addAdditionalTomcatConnectors(createSslConnector());
return tomcat;
}
private Connector createSslConnector() {
Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
Http11NioProtocol protocol = (Http11NioProtocol) connector.getProtocolHandler();
try {
File keystore = new ClassPathResource("keystore").getFile();
File truststore = new ClassPathResource("keystore").getFile();
connector.setScheme("https");
connector.setSecure(true);
connector.setPort(8443);
protocol.setSSLEnabled(true);
protocol.setKeystoreFile(keystore.getAbsolutePath());
protocol.setKeystorePass("changeit");
protocol.setTruststoreFile(truststore.getAbsolutePath());
protocol.setTruststorePass("changeit");
protocol.setKeyAlias("apitester");
return connector;
} catch (IOException ex) {
throw new IllegalStateException("can't access keystore: [" + "keystore"
+ "] or truststore: [" + "keystore" + "]", ex);
}
}
}
Problem is that I don't see or find how I should setup these connectors so they serve from my angularJS build folder.
Upon searching I came upon Spring-Boot : How can I add tomcat connectors to bind to controller but I'm not sure if in that solution I should change my current application or make a parent application for both applications.
My current application main looks like this:
#Configuration
#ComponentScan({"be.ugent.lca","be.ugent.sherpa.configuration"})
#EnableAutoConfiguration
#EnableSpringDataWebSupport
public class Application extends SpringBootServletInitializer{
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
If possible I'd like some more info about what connectors are in the spring-boot context.
If this is not the way to go I'd like someone to be able to conform this second solution or suggest a change in my code.
I'm really not sure enough about these solution that I want to go breaking my application over it. (though it's backed up with github)
Just place your AngularJS + other front-end assets into src/main/resources/static folder, Spring Boot will serve them automatically.

Bundling in Web API

I trying to bundle my SPA and I just can't get it to work.
My Tech Stack
WebAPI 1.0
AngularJs 1.3.X
I am just using vanilla HTML with Angular Calls to Backend WebAPI controllers. Since I am using vanilla HTML and not MVC views can I even use bundling. Do I need to return the bundled url from a WebAPI Controller?
I see it's been a year since you posted the question, but I found this post that I think answers the question in your problem.
Bundling and minification without ASP.NET MVC
It actually gives instructions on how to enable it.
First you have to check if you have installed the Nuget Package Microsoft.AspNet.Web.Optimization
(Tools -> Nuget Package Manager -> Manage Nuget Packages for Solution)
Create a BundleConfig Class and define your bundles:
using System.Web.Optimization;
public class BundleConfig
{
public static void RegisterBundles(BundleCollection bundles)
{
bundles.Add(new ScriptBundle("~/bundles/js").Include(
"~/Scripts/*.js"));
bundles.Add(new StyleBundle("~/bundles/css").Include(
"~/Styles/*.css"));
}
}
Register the BundleConfig class within the application start in the global.asax:
void Application_Start(object sender, EventArgs e)
{
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
Reference the bundles in your HTML document.
Enable bundling by disabling debug mode.

Two projects in one solution

I have two projects in my Visual Studio solution. One is an empty WEB API application with AngularJS and html front-end. Other is WEB API project with embedded database, controllers and stuff. The problem is when I call web api controllers from my first solution, I'm getting 404 not found. I suspect there is a problem in a hosting, but I don't know what kind exactly. I tried to host back-end project in IIS, but no results. Maybe there is something I missed.
After a lot time spent on investigating this, I realised that it was problem with different ports in localhost, the solution can be found there:http://jaliyaudagedara.blogspot.com/2014/08/angularjs-consuming-aspnet-web-api.html.
Basically I should change the project URL in properties to match the front-end project's localhost port and add an 'api' suffix to avoid using the same virtual directory by both projects.
#satish,
Global.asax:
namespace WebAPI_Training
{
public class WebApiApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
GlobalConfiguration.Configure(WebApiConfig.Register);
}
}
}
WebApiConfig.cs:
namespace WebAPI_Training
{
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
var jsonFormatter = config.Formatters.OfType<JsonMediaTypeFormatter>().First();
jsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
}
}
}

Resources