4

We have an existing Web API project that we want to now serve 2 clients from root as well (accessed via different subdomains). What is the right way to setup Web API to perform the functions of serving files for two websites and hitting routes?

I see two major options:

  1. Use Kestrel as a file server. I'm not sure how I would configure Kestrel to serve two sites from root (coming from different subdomains). It seems have minimal configuration exposed as is, and this doesn't seem extensible to serve 2 sites based on subdomain.

    var host = new WebHostBuilder()
       .UseKestrel()
       .UseWebRoot("wwwroot")
       .UseIISIntegration()
       .UseStartup<Startup>()
       .Build();
    
    host.Run();
    

    Furthermore, I'm currently having trouble integrating Kestrel with Web API, see this StackOverflow question.

  2. Serve files from a Web API controller that is responsible for root. This would read the URL and return the proper index.html. From there I'm not sure how it would serve other files that index.html references, like js/app.js, css/core.css, or assets/*. Individual controllers could be made to handle these, but that seems fragile.

Which of these approaches is appropriate? Or is there something else I have not considered to accomplish this end?

Scotty H
  • 6,432
  • 6
  • 41
  • 94
  • 3
    What I do not understand is why you would like to mix ASP.NET Core (using Kestrel) and Web API (System.Web) in the same project. Their architecture is totally different (and I think incompatible). You may consider using Owin [native routing capabilities](https://stackoverflow.com/a/25405782/3670737) and serve static files with something similar to [app.UseStaticFiles()](https://msdn.microsoft.com/en-us/library/owin.staticfileextensions.usestaticfiles(v=vs.113).aspx). – Federico Dipuma May 25 '17 at 20:44
  • 1
    I ended up using OWIN and it worked nicely for my needs. Combining the information in the links in the previous comment directly led to implementing a solution. Thanks @FedericoDipuma! – Scotty H May 29 '17 at 22:50

1 Answers1

1

As per @FedericoDipuma's comment, I ended up using OWIN with the following Startup.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Owin;
using Microsoft.Owin.FileSystems;
using Microsoft.Owin.StaticFiles;
using System.IO;

namespace SealingServer
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            app.MapWhen(ctx => ctx.Request.Headers.Get("Host").Equals("subdomain1.site.com"), app2 =>
            {
                var firstClientRoot = Path.Combine("./firstClient/");
                var firstClientFileSystem = new PhysicalFileSystem(firstClientRoot);

                var fileServerOptions = new FileServerOptions();
                fileServerOptions.EnableDefaultFiles = true;
                fileServerOptions.FileSystem = firstClientFileSystem;
                fileServerOptions.DefaultFilesOptions.DefaultFileNames = new[] {"home.html"};
                fileServerOptions.StaticFileOptions.OnPrepareResponse = staticFileResponseContext =>
                {
                    staticFileResponseContext.OwinContext.Response.Headers.Add("Cache-Control", new[] { "public", "max-age=0" });
                };

                app2.UseFileServer(fileServerOptions);
            });
            app.MapWhen(ctx => ctx.Request.Headers.Get("Host").Equals("subdomain2.site.com"), app2 =>  
            {
                var secondClientRoot = Path.Combine("./secondClient/");
                var secondClientFileSystem = new PhysicalFileSystem(secondClientRoot);

                var fileServerOptions = new FileServerOptions();
                fileServerOptions.EnableDefaultFiles = true;
                fileServerOptions.FileSystem = secondClientFileSystem;
                fileServerOptions.DefaultFilesOptions.DefaultFileNames = new[] { "home.html" };
                fileServerOptions.StaticFileOptions.OnPrepareResponse = staticFileResponseContext =>
                {
                    staticFileResponseContext.OwinContext.Response.Headers.Add("Cache-Control", new[] { "public", "max-age=0" });
                };

                app2.UseFileServer(fileServerOptions);
            });
        }
    }
}
Scotty H
  • 6,432
  • 6
  • 41
  • 94