public static IApplicationBuilder UseNodeModules(this IApplicationBuilder appBuilder, string roothPath) { var path = Path.Combine(roothPath, "node_modules"); var provider = new PhysicalFileProvider(path); var options = new StaticFileOptions() { RequestPath = "/node_modules", FileProvider = provider }; appBuilder.UseStaticFiles(options); return(appBuilder); }
public static IApplicationBuilder UseNodeModules( this IApplicationBuilder app, string root) { var path = Path.Combine(root, "node_modules"); //to get the path seperator for different OS like Linux/Windows var fileProvider = new PhysicalFileProvider(path); var options = new StaticFileOptions(); options.RequestPath = "/node_modules"; options.FileProvider = fileProvider; app.UseStaticFiles(options); return(app); }
public static IApplicationBuilder UseNodeModules( this IApplicationBuilder app, string root) { var path = Path.Combine(root, "node_modules"); var fileProvider = new PhysicalFileProvider(path); var options = new StaticFileOptions(); options.RequestPath = "/node_modules"; options.FileProvider = fileProvider; app.UseStaticFiles(options); return(app); }
public static IApplicationBuilder UseNodeModules(this IApplicationBuilder app, HostingEnvironment env) { var path = Path.Combine(env.ContentRootPath, "node_modules"); var provider = new PhysicalFileProvider(path); var options = new StaticFileOptions(); options.RequestPath = "/node_modules"; options.FileProvider = provider; app.UseStaticFiles(options); return(app); }
private static StaticFilesEndpointConventionBuilder MapStaticFilesCore(IEndpointRouteBuilder endpoints, PathString requestPath, StaticFileEndpointOptions options) { StaticFileOptions staticFileOptions; if (options == null) { var original = endpoints.ServiceProvider.GetRequiredService <IOptions <StaticFileOptions> >(); staticFileOptions = new StaticFileOptions() { ContentTypeProvider = original.Value.ContentTypeProvider, DefaultContentType = original.Value.DefaultContentType, FileProvider = original.Value.FileProvider, HttpsCompression = original.Value.HttpsCompression, OnPrepareResponse = original.Value.OnPrepareResponse, ServeUnknownFileTypes = original.Value.ServeUnknownFileTypes, }; } else { staticFileOptions = new StaticFileOptions() { ContentTypeProvider = options.ContentTypeProvider, DefaultContentType = options.DefaultContentType, FileProvider = options.FileProvider, HttpsCompression = options.HttpsCompression, OnPrepareResponse = options.OnPrepareResponse, ServeUnknownFileTypes = options.ServeUnknownFileTypes, }; } staticFileOptions.ContentTypeProvider ??= new FileExtensionContentTypeProvider(); staticFileOptions.FileProvider ??= endpoints.ServiceProvider.GetRequiredService <IWebHostEnvironment>().WebRootFileProvider; staticFileOptions.RequestPath = requestPath; var pattern = RoutePatternFactory.Parse(requestPath + "/{**path}", defaults: null, parameterPolicies: new { path = new FileExistsConstraint(options.FileProvider), }); var app = endpoints.CreateApplicationBuilder(); // Temporary hack app.Use(next => httpContext => { httpContext.SetEndpoint(null); return(next(httpContext)); }); app.UseStaticFiles(staticFileOptions); return(new StaticFilesEndpointConventionBuilder(endpoints.Map(pattern, app.Build()))); }
public static IApplicationBuilder UseNodeModules(this IApplicationBuilder app, string rootPath) { // Combine the rootpath to the node_modules to get the absolute path var path = Path.Combine(rootPath, "node_modules"); var fileProvider = new PhysicalFileProvider(path); var options = new StaticFileOptions { RequestPath = "/node_modules", FileProvider = fileProvider }; app.UseStaticFiles(options); return(app); }
/// <summary> /// Configures the middleware pipeline to work with Blazor. /// </summary> /// <param name="applicationBuilder"></param> /// <param name="options"></param> public static void UseBlazor( this IApplicationBuilder applicationBuilder, BlazorOptions options) { // TODO: Make the .blazor.config file contents sane // Currently the items in it are bizarre and don't relate to their purpose, // hence all the path manipulation here. We shouldn't be hardcoding 'dist' here either. var env = (IHostingEnvironment)applicationBuilder.ApplicationServices.GetService(typeof(IHostingEnvironment)); var config = BlazorConfig.Read(options.ClientAssemblyPath); var distDirStaticFiles = new StaticFileOptions { FileProvider = new PhysicalFileProvider(config.DistPath), ContentTypeProvider = CreateContentTypeProvider(), }; // First, match the request against files in the client app dist directory applicationBuilder.UseStaticFiles(distDirStaticFiles); // Next, match the request against static files in wwwroot if (!string.IsNullOrEmpty(config.WebRootPath)) { // In development, we serve the wwwroot files directly from source // (and don't require them to be copied into dist). // TODO: When publishing is implemented, have config.WebRootPath set // to null so that it only serves files that were copied to dist applicationBuilder.UseStaticFiles(new StaticFileOptions { FileProvider = new PhysicalFileProvider(config.WebRootPath) }); } // Definitely don't open a listener for live reloading in production, even if the // client app was compiled with live reloading enabled if (env.IsDevelopment()) { // Whether or not live reloading is actually enabled depends on the client config // For release builds, it won't be (by default) applicationBuilder.UseBlazorLiveReloading(config); } // Finally, use SPA fallback routing (serve default page for anything else, // excluding /_framework/*) applicationBuilder.MapWhen(IsNotFrameworkDir, childAppBuilder => { childAppBuilder.UseSpa(spa => { spa.Options.DefaultPageStaticFileOptions = distDirStaticFiles; }); }); }
public static IApplicationBuilder UseBowerComponents(this IApplicationBuilder app, string root) { var path = Path.Combine(root, "bower_components"); var provider = new PhysicalFileProvider(path); var options = new StaticFileOptions(); options.RequestPath = "/bower_components"; options.FileProvider = provider; app.UseStaticFiles(options); return(app); }
public static IApplicationBuilder UseNodeModules(this IApplicationBuilder app, string root) { //build the absolute path for the node modules folder var path = Path.Combine(root, "node_modules"); var fileProvider = new PhysicalFileProvider(path); var options = new StaticFileOptions(); //only respond to requests for /node_modules options.RequestPath = "/node_modules"; // options.FileProvider = fileProvider; app.UseStaticFiles(options); return(app); }
public static StaticFileOptions AddRazorClassLibraryStaticFiles <T>(this StaticFileOptions options, IWebHostEnvironment environment, string rootPath = "wwwroot") { options = options ?? throw new ArgumentNullException(nameof(options)); // Basic initialization in case the options weren't initialized by any other component options.ContentTypeProvider = options.ContentTypeProvider ?? new FileExtensionContentTypeProvider(); if (options.FileProvider == null && environment.WebRootFileProvider == null) { throw new InvalidOperationException("Missing FileProvider."); } options.FileProvider = options.FileProvider ?? environment.WebRootFileProvider; // Add our provider var filesProvider = new ManifestEmbeddedFileProvider(typeof(T).Assembly, rootPath); options.FileProvider = new CompositeFileProvider(options.FileProvider, filesProvider); return(options); }
public static IApplicationBuilder UseNodeModules(this IApplicationBuilder app, string root) { //get path of node modules and create a file provider with it var path = Path.Combine(root, "node_modules"); var fileProvider = new PhysicalFileProvider(path); //create a staticfileoptions and change these values in it. var options = new StaticFileOptions(); options.RequestPath = "/node_modules"; options.FileProvider = fileProvider; //now you can use static files from the options app.UseStaticFiles(options); return(app); }
private static StaticFileOptions CreateStaticFilesOptions(IFileProvider webRootFileProvider) { var options = new StaticFileOptions(); options.FileProvider = webRootFileProvider; var contentTypeProvider = new FileExtensionContentTypeProvider(); AddMapping(contentTypeProvider, ".dll", MediaTypeNames.Application.Octet); // We unconditionally map pdbs as there will be no pdbs in the output folder for // release builds unless BlazorEnableDebugging is explicitly set to true. AddMapping(contentTypeProvider, ".pdb", MediaTypeNames.Application.Octet); AddMapping(contentTypeProvider, ".br", MediaTypeNames.Application.Octet); AddMapping(contentTypeProvider, ".dat", MediaTypeNames.Application.Octet); AddMapping(contentTypeProvider, ".blat", MediaTypeNames.Application.Octet); options.ContentTypeProvider = contentTypeProvider; // Static files middleware will try to use application/x-gzip as the content // type when serving a file with a gz extension. We need to correct that before // sending the file. options.OnPrepareResponse = fileContext => { // At this point we mapped something from the /_framework fileContext.Context.Response.Headers.Append(HeaderNames.CacheControl, "no-cache"); var requestPath = fileContext.Context.Request.Path; var fileExtension = Path.GetExtension(requestPath.Value); if (string.Equals(fileExtension, ".gz") || string.Equals(fileExtension, ".br")) { // When we are serving framework files (under _framework/ we perform content negotiation // on the accept encoding and replace the path with <<original>>.gz|br if we can serve gzip or brotli content // respectively. // Here we simply calculate the original content type by removing the extension and apply it // again. // When we revisit this, we should consider calculating the original content type and storing it // in the request along with the original target path so that we don't have to calculate it here. var originalPath = Path.GetFileNameWithoutExtension(requestPath.Value); if (originalPath != null && contentTypeProvider.TryGetContentType(originalPath, out var originalContentType)) { fileContext.Context.Response.ContentType = originalContentType; } } }; return(options); }
/// <summary> /// Extension method to serve files from the Node_Modules folder /// </summary> /// <param name="app"></param> /// <returns></returns> public static IApplicationBuilder UseNodeModules(this IApplicationBuilder app, IHostingEnvironment env) { //Get the absolute path to the node_modules folder var path = Path.Combine(env.ContentRootPath, "node_modules"); //PhysicalFileProvider used to access the actual physical files available on the Disk via File System var provider = new PhysicalFileProvider(path); //Used to set up where to looak at to get the files var options = new StaticFileOptions { RequestPath = "/node_modules", FileProvider = provider }; app.UseStaticFiles(options); return(app); }
/// <summary> /// Adds a <see cref="StaticFileMiddleware"/> that will serve static files from the client-side Blazor application /// specified by <paramref name="clientAssemblyFilePath"/>. /// </summary> /// <param name="clientAssemblyFilePath">The file path of the client-side Blazor application assembly.</param> /// <param name="app">The <see cref="IApplicationBuilder"/>.</param> /// <returns>The <see cref="IApplicationBuilder"/>.</returns> public static IApplicationBuilder UseClientSideBlazorFiles(this IApplicationBuilder app, string clientAssemblyFilePath) { if (clientAssemblyFilePath == null) { throw new ArgumentNullException(nameof(clientAssemblyFilePath)); } var fileProviders = new List <IFileProvider>(); // TODO: Make the .blazor.config file contents sane // Currently the items in it are bizarre and don't relate to their purpose, // hence all the path manipulation here. We shouldn't be hardcoding 'dist' here either. var config = BlazorConfig.Read(clientAssemblyFilePath); // First, match the request against files in the client app dist directory fileProviders.Add(new PhysicalFileProvider(config.DistPath)); // * Before publishing, we serve the wwwroot files directly from source // (and don't require them to be copied into dist). // In this case, WebRootPath will be nonempty if that directory exists. // * After publishing, the wwwroot files are already copied to 'dist' and // will be served by the above middleware, so we do nothing here. // In this case, WebRootPath will be empty (the publish process sets this). if (!string.IsNullOrEmpty(config.WebRootPath)) { fileProviders.Add(new PhysicalFileProvider(config.WebRootPath)); } // We can't modify an IFileContentTypeProvider, so we have to decorate. var contentTypeProvider = new FileExtensionContentTypeProvider(); AddMapping(contentTypeProvider, ".dll", MediaTypeNames.Application.Octet); if (config.EnableDebugging) { AddMapping(contentTypeProvider, ".pdb", MediaTypeNames.Application.Octet); } var options = new StaticFileOptions() { ContentTypeProvider = contentTypeProvider, FileProvider = new CompositeFileProvider(fileProviders), OnPrepareResponse = CacheHeaderSettings.SetCacheHeaders, }; app.UseStaticFiles(options); return(app);
/// <summary> /// Adds a specialized <see cref="RouteEndpoint"/> to the <see cref="IEndpointRouteBuilder"/> that will match /// requests for non-filenames with the lowest possible priority. The request will be routed to a /// <see cref="StaticFileMiddleware"/> that attempts to serve the file specified by <paramref name="filePath"/>. /// </summary> /// <param name="builder">The <see cref="IEndpointRouteBuilder"/>.</param> /// <param name="filePath">The file path of the file to serve.</param> /// <param name="options"><see cref="StaticFileOptions"/> for the <see cref="StaticFileMiddleware"/>.</param> /// <returns>The <see cref="IEndpointRouteBuilder"/></returns> /// <remarks> /// <para> /// <see cref="MapFallbackToFile(IEndpointRouteBuilder, string, StaticFileOptions)"/> is intended to handle cases /// where URL path of the request does not contain a file name, and no other endpoint has matched. This is convenient /// for routing requests for dynamic content to a SPA framework, while also allowing requests for non-existent files to /// result in an HTTP 404. /// </para> /// <para> /// <see cref="MapFallbackToFile(IEndpointRouteBuilder, string, StaticFileOptions)"/> registers an endpoint using the pattern /// <c>{*path:nonfile}</c>. The order of the registered endpoint will be <c>int.MaxValue</c>. /// </para> /// </remarks> public static IEndpointConventionBuilder MapFallbackToFile( this IEndpointRouteBuilder builder, string filePath, StaticFileOptions options) { if (builder == null) { throw new ArgumentNullException(nameof(builder)); } if (filePath == null) { throw new ArgumentNullException(nameof(filePath)); } return(builder.MapFallback(CreateRequestDelegate(builder, filePath, options))); }
/// <summary> /// Configures the middleware pipeline to work with Blazor. /// </summary> /// <param name="applicationBuilder"></param> /// <param name="options"></param> public static void UseBlazor( this IApplicationBuilder applicationBuilder, BlazorOptions options) { // TODO: Make the .blazor.config file contents sane // Currently the items in it are bizarre and don't relate to their purpose, // hence all the path manipulation here. We shouldn't be hardcoding 'dist' here either. var env = (IHostingEnvironment)applicationBuilder.ApplicationServices.GetService(typeof(IHostingEnvironment)); var config = BlazorConfig.Read(options.ClientAssemblyPath); var clientAppBinDir = Path.GetDirectoryName(config.SourceOutputAssemblyPath); var clientAppDistDir = Path.Combine( env.ContentRootPath, Path.Combine(clientAppBinDir, "dist")); var distDirStaticFiles = new StaticFileOptions { FileProvider = new PhysicalFileProvider(clientAppDistDir), ContentTypeProvider = CreateContentTypeProvider(), }; // First, match the request against files in the client app dist directory applicationBuilder.UseStaticFiles(distDirStaticFiles); // Next, match the request against static files in wwwroot if (!string.IsNullOrEmpty(config.WebRootPath)) { // In development, we serve the wwwroot files directly from source // (and don't require them to be copied into dist). // TODO: When publishing is implemented, have config.WebRootPath set // to null so that it only serves files that were copied to dist applicationBuilder.UseStaticFiles(new StaticFileOptions { FileProvider = new PhysicalFileProvider(config.WebRootPath) }); } // Finally, use SPA fallback routing (serve default page for anything else, // excluding /_framework/*) applicationBuilder.MapWhen(IsNotFrameworkDir, childAppBuilder => { childAppBuilder.UseSpa(spa => { spa.Options.DefaultPageStaticFileOptions = distDirStaticFiles; }); }); }
/// <summary> /// Adds a low-priority endpoint that will serve the the file specified by <paramref name="filePath"/> from the client-side /// Blazor application specified by <paramref name="clientAssemblyFilePath"/>. /// </summary> /// <param name="clientAssemblyFilePath">The file path of the client-side Blazor application assembly.</param> /// <param name="endpoints">The <see cref="IEndpointRouteBuilder"/>.</param> /// <param name="pattern">The route pattern to match.</param> /// <param name="filePath"> /// The relative path to the entry point of the client-side application. The path is relative to the /// <see cref="IWebHostEnvironment.WebRootPath"/>, commonly <c>wwwroot</c>. /// </param> /// <returns>The <see cref="IApplicationBuilder"/>.</returns> /// <remarks> /// <para> /// This method is intended to handle cases where URL path of the request does not contain a filename, and no other /// endpoint has matched. This is convenient for routing requests for dynamic content to the client-side blazor /// application, while also allowing requests for non-existent files to result in an HTTP 404. /// </para> /// </remarks> public static IEndpointConventionBuilder MapFallbackToClientSideBlazor(this IEndpointRouteBuilder endpoints, string clientAssemblyFilePath, string pattern, string filePath) { if (endpoints == null) { throw new ArgumentNullException(nameof(endpoints)); } if (clientAssemblyFilePath == null) { throw new ArgumentNullException(nameof(clientAssemblyFilePath)); } if (pattern == null) { throw new ArgumentNullException(nameof(pattern)); } if (filePath == null) { throw new ArgumentNullException(nameof(filePath)); } var config = BlazorConfig.Read(clientAssemblyFilePath); // We want to serve "index.html" from whichever directory contains it in this priority order: // 1. Client app "dist" directory // 2. Client app "wwwroot" directory // 3. Server app "wwwroot" directory var directory = endpoints.ServiceProvider.GetRequiredService <IWebHostEnvironment>().WebRootPath; var indexHtml = config.FindIndexHtmlFile(); if (indexHtml != null) { directory = Path.GetDirectoryName(indexHtml); } var options = new StaticFileOptions() { FileProvider = new PhysicalFileProvider(directory), OnPrepareResponse = CacheHeaderSettings.SetCacheHeaders, }; return(endpoints.MapFallbackToFile(pattern, filePath, options)); }
public static IApplicationBuilder UseNodeModules(this IApplicationBuilder app, string root) { var path = Path.Combine(root, "node_modules"); if (!Directory.Exists(path)) { throw new NotImplementedException("Directory node_modules not found."); } var fileProvider = new PhysicalFileProvider(path); var options = new StaticFileOptions(); options.RequestPath = "/node_modules"; options.FileProvider = fileProvider; app.UseStaticFiles(options); return(app); }
/// <summary> /// Custom Middleware used to set up a seperate location for serving static files. /// Specific to the folder we want to serve files from. /// </summary> /// <param name="app"></param> /// <param name="root"></param> /// <returns></returns> public static IApplicationBuilder UseNodeModules(this IApplicationBuilder app, string root) { // Create a path from the root path/string passed in and then the node_modules folder var path = Path.Combine(root, "node_modules"); // Set up the path to the node_modules folder as a File Provider so we can set it up for our File Options object var provider = new PhysicalFileProvider(path); // Create an options object to hold any options needed for StaticFiles using node_modules folder var options = new StaticFileOptions(); // Ignore any requests if they don't beging with /node_modules options.RequestPath = "/node_modules"; // Where to look for the files options.FileProvider = provider; app.UseStaticFiles(options); return(app); }
public static IApplicationBuilder UseMvcJQueryDataTables(this IApplicationBuilder app) { var settings = app.ApplicationServices.GetService <global::Mvc.JQuery.DataTables.Settings>(); if (settings == null) { throw new InvalidOperationException("Unable to find the required services. Please add all the required services by calling 'IServiceCollection.{}' inside the call to 'ConfigureServices(...)' in the application startup code."); } app.UseStaticFiles(); { var options = new StaticFileOptions { RequestPath = "", FileProvider = settings.FileProvider }; app.UseStaticFiles(options); } return(app); }
/// <summary> /// Configures the middleware pipeline to work with Blazor. /// </summary> /// <param name="applicationBuilder"></param> /// <param name="options"></param> public static void UseBlazor( this IApplicationBuilder applicationBuilder, BlazorOptions options) { var config = BlazorConfig.Read(options.ClientAssemblyPath); var clientAppBinDir = Path.GetDirectoryName(config.SourceOutputAssemblyPath); var clientAppDistDir = Path.Combine(clientAppBinDir, "dist"); var distDirStaticFiles = new StaticFileOptions { FileProvider = new PhysicalFileProvider(clientAppDistDir), ContentTypeProvider = CreateContentTypeProvider(), }; // First, match the request against files in the client app dist directory applicationBuilder.UseStaticFiles(distDirStaticFiles); // Next, match the request against static files in wwwroot if (!string.IsNullOrEmpty(config.WebRootPath)) { // In development, we serve the wwwroot files directly from source // (and don't require them to be copied into dist). // TODO: When publishing is implemented, have config.WebRootPath set // to null so that it only serves files that were copied to dist applicationBuilder.UseStaticFiles(new StaticFileOptions { FileProvider = new PhysicalFileProvider(config.WebRootPath) }); } // Finally, use SPA fallback routing (serve default page for anything else, // excluding /_framework/*) applicationBuilder.MapWhen(IsNotFrameworkDir, childAppBuilder => { childAppBuilder.UseSpa(spa => { spa.Options.DefaultPageStaticFileOptions = distDirStaticFiles; }); }); }
/// <summary> /// Adds a specialized <see cref="RouteEndpoint"/> to the <see cref="IEndpointRouteBuilder"/> that will match /// requests for non-filenames with the lowest possible priority. The request will be routed to a /// <see cref="StaticFileMiddleware"/> that attempts to serve the file specified by <paramref name="filePath"/>. /// </summary> /// <param name="endpoints">The <see cref="IEndpointRouteBuilder"/>.</param>\ /// <param name="pattern">The route pattern.</param> /// <param name="filePath">The file path of the file to serve.</param> /// <param name="options"><see cref="StaticFileOptions"/> for the <see cref="StaticFileMiddleware"/>.</param> /// <returns>The <see cref="IEndpointRouteBuilder"/></returns> /// <remarks> /// <para> /// <see cref="MapFallbackToFile(IEndpointRouteBuilder, string, string, StaticFileOptions)"/> is intended to handle /// cases where URL path of the request does not contain a filename, and no other endpoint has matched. This is /// convenient for routing requests for dynamic content to a SPA framework, while also allowing requests for /// non-existent files to result in an HTTP 404. /// </para> /// <para> /// The order of the registered endpoint will be <c>int.MaxValue</c>. /// </para> /// <para> /// This overload will use the provided <paramref name="pattern"/> verbatim. Use the <c>:nonfile</c> route contraint /// to exclude requests for static files. /// </para> /// </remarks> public static IEndpointConventionBuilder MapFallbackToFile( this IEndpointRouteBuilder endpoints, string pattern, string filePath, StaticFileOptions options) { if (endpoints == null) { throw new ArgumentNullException(nameof(endpoints)); } if (pattern == null) { throw new ArgumentNullException(nameof(filePath)); } if (filePath == null) { throw new ArgumentNullException(nameof(filePath)); } return(endpoints.MapFallback(pattern, CreateRequestDelegate(endpoints, filePath, options))); }
/// <summary> /// Enables static file serving with the given options /// </summary> /// <param name="app"></param> /// <param name="options"></param> /// <returns></returns> public static IApplicationBuilder UseStaticFiles(this IApplicationBuilder app, StaticFileOptions options) { if (app == null) { throw new ArgumentNullException(nameof(app)); } if (options == null) { throw new ArgumentNullException(nameof(options)); } return(app.UseMiddleware <StaticFileMiddleware>(Options.Create(options))); }
/// <summary> /// Configures the middleware pipeline to work with Blazor. /// </summary> /// <param name="app"></param> /// <param name="options"></param> public static void UseBlazor( this IApplicationBuilder app, BlazorOptions options) { // TODO: Make the .blazor.config file contents sane // Currently the items in it are bizarre and don't relate to their purpose, // hence all the path manipulation here. We shouldn't be hardcoding 'dist' here either. var env = (IHostingEnvironment)app.ApplicationServices.GetService(typeof(IHostingEnvironment)); var config = BlazorConfig.Read(options.ClientAssemblyPath); var distDirStaticFiles = new StaticFileOptions { FileProvider = new PhysicalFileProvider(config.DistPath), ContentTypeProvider = CreateContentTypeProvider(config.EnableDebugging), OnPrepareResponse = SetCacheHeaders }; if (env.IsDevelopment() && config.EnableAutoRebuilding) { if (env.ApplicationName.Equals(DevServerApplicationName, StringComparison.OrdinalIgnoreCase)) { app.UseDevServerAutoRebuild(config); } else { app.UseHostedAutoRebuild(config, env.ContentRootPath); } } // First, match the request against files in the client app dist directory app.UseStaticFiles(distDirStaticFiles); // Next, match the request against static files in wwwroot if (!string.IsNullOrEmpty(config.WebRootPath)) { // In development, we serve the wwwroot files directly from source // (and don't require them to be copied into dist). // TODO: When publishing is implemented, have config.WebRootPath set // to null so that it only serves files that were copied to dist app.UseStaticFiles(new StaticFileOptions { FileProvider = new PhysicalFileProvider(config.WebRootPath), OnPrepareResponse = SetCacheHeaders }); } // Accept debugger connections if (config.EnableDebugging) { app.UseMonoDebugProxy(); } // Finally, use SPA fallback routing (serve default page for anything else, // excluding /_framework/*) app.MapWhen(IsNotFrameworkDir, childAppBuilder => { childAppBuilder.UseSpa(spa => { spa.Options.DefaultPageStaticFileOptions = distDirStaticFiles; }); }); }