Static files and WebOptimization bundles not found after ASP.NET project has been converted to a Topshelf service

169 views Asked by At

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 ❌: WebOptimizer example

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.

0

There are 0 answers