I have an existing .NET 6 web project (ASP.NET MVC) which was using the new styled initialization - everything in Program.cs. So far so good, everything is running smoothly at this stage.
I'm turning it into a Topshelp (Windows) service, which requires a breakdown to the 'old' way - Startup.cs + Program.cs. The project builds, runs, and loads in the browser. However, after the conversion/split I can no longer access any of my static files nor WebOptimizer bundles.
I cannot access them by URL - https://localhost:[port]/css/all.css
comes back as 404 ❌
WebOptimizer middleware is unable to pick-up on bundles it has created moments before ❌:
I'm sure I'm missing something small, but I simply cannot figure out what (considering it builds, runs, and loads, albeit as ugly as a sin).
Here are my current Program + Startup.cs (redundant parts cut/reduced for brevity):
Startup.cs
public class Startup
{
public IConfiguration Configuration { get; }
public Startup(IWebHostEnvironment env)
{
Console.WriteLine($"using {env.EnvironmentName} settings");
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
.AddEnvironmentVariables();
Configuration = builder.Build();
}
public void Configureservices(IServiceCollection services)
{
ILog Log = LogManager.GetLogger(typeof(Program));
services.AddControllersWithViews();
//services.AddAuthentication() stuff here...
//services.AddLogging() stuff here...
//services.AddAuthorization() stuff here...
//Dependency Injection here...
services.AddRazorPages();
services.AddWindowsService();
//services.AddDbContex() stuff here...
services.AddMemoryCache();
services.AddWebOptimizer(pipeline =>
{
pipeline.AddCssBundle("~/css/themebundle.css", "~/themes/base/*.css");
pipeline.AddCssBundle("~/css/highlightbundle.css", "~/highlight/styles/*.css");
pipeline.AddJavaScriptBundle("~/bundles/highlight", "~/Scripts/highlight.pack.js");
});
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.EnvironmentName != "Test")
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
if (env.EnvironmentName == "Test")
{
app.UsePathBase("/MyNecessaryBasePath");
}
app.UseWebOptimizer();
app.UseStaticFiles(new StaticFileOptions
{
RequestPath = "/MyNecessaryBasePath"
});
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapControllerRoute(
name: "Default",
pattern: "{controller=MyController}/{action=MyAction}/{id?}"
);
});
}
}
and my Program.cs
public class Program
{
private IHost? _host;
public static void Main(string[] args)
{
new Program().Startup(args);
}
public void Startup(string[] args)
{
HostFactory.Run(x =>
{
x.Service<Program>(s =>
{
s.ConstructUsing(name => new Program());
s.WhenStarted(tc => tc.Start(args));
s.WhenStopped(tc => tc.Stop());
}
);
x.SetDisplayName("DisplayName");
x.SetDescription("Description");
x.SetServiceName("ServiceName");
x.UseLog4Net("log4net.xml");
});
}
public void Start(string[] args)
{
// Add services to the container.
_host = CreateHostBuilder(args).Build();
_host.StartAsync(CancellationToken.None);
}
public void Stop()
{
_host?.StopAsync(CancellationToken.None);
_host?.Dispose();
}
public static IHostBuilder CreateHostBuilder(string[] args)
{
return Host
.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
})
.ConfigureLogging(builder => builder.AddLog4Net("log4net.xml"));
}
}
The app.UseStaticFiles(new StaticFileOptions {RequestPath = "/MyNecessaryBasePath"});
is something I picked up while googling for a solution, but unfortunately, it didn't change much.