From 15d2f5a898da584433e38c82d5b09c375d9f87b7 Mon Sep 17 00:00:00 2001 From: Steve Sanderson Date: Tue, 2 Jan 2018 15:44:59 +0000 Subject: [PATCH] Allow explicit configuration of StaticFileOptions in new SPA APIs. Fixes #1424. --- .../SpaDefaultPageMiddleware.cs | 2 +- .../SpaOptions.cs | 7 +- .../StaticFiles/SpaStaticFilesExtensions.cs | 70 ++++++++++++------- 3 files changed, 51 insertions(+), 28 deletions(-) diff --git a/src/Microsoft.AspNetCore.SpaServices.Extensions/SpaDefaultPageMiddleware.cs b/src/Microsoft.AspNetCore.SpaServices.Extensions/SpaDefaultPageMiddleware.cs index d39c49f..c3c540b 100644 --- a/src/Microsoft.AspNetCore.SpaServices.Extensions/SpaDefaultPageMiddleware.cs +++ b/src/Microsoft.AspNetCore.SpaServices.Extensions/SpaDefaultPageMiddleware.cs @@ -31,7 +31,7 @@ namespace Microsoft.AspNetCore.SpaServices // Developers who need to host more than one SPA with distinct default pages can // override the file provider app.UseSpaStaticFilesInternal( - overrideFileProvider: options.DefaultPageFileProvider, + options.DefaultPageStaticFileOptions ?? new StaticFileOptions(), allowFallbackOnServingWebRootFiles: true); // If the default file didn't get served as a static file (usually because it was not diff --git a/src/Microsoft.AspNetCore.SpaServices.Extensions/SpaOptions.cs b/src/Microsoft.AspNetCore.SpaServices.Extensions/SpaOptions.cs index 912c290..f44b820 100644 --- a/src/Microsoft.AspNetCore.SpaServices.Extensions/SpaOptions.cs +++ b/src/Microsoft.AspNetCore.SpaServices.Extensions/SpaOptions.cs @@ -1,6 +1,7 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.FileProviders; @@ -29,7 +30,7 @@ namespace Microsoft.AspNetCore.SpaServices internal SpaOptions(SpaOptions copyFromOptions) { _defaultPage = copyFromOptions.DefaultPage; - DefaultPageFileProvider = copyFromOptions.DefaultPageFileProvider; + DefaultPageStaticFileOptions = copyFromOptions.DefaultPageStaticFileOptions; SourcePath = copyFromOptions.SourcePath; } @@ -52,14 +53,14 @@ namespace Microsoft.AspNetCore.SpaServices } /// - /// Gets or sets the that supplies content + /// Gets or sets the that supplies content /// for serving the SPA's default page. /// /// If not set, a default file provider will read files from the /// , which by default is /// the wwwroot directory. /// - public IFileProvider DefaultPageFileProvider { get; set; } + public StaticFileOptions DefaultPageStaticFileOptions { get; set; } /// /// Gets or sets the path, relative to the application working directory, diff --git a/src/Microsoft.AspNetCore.SpaServices.Extensions/StaticFiles/SpaStaticFilesExtensions.cs b/src/Microsoft.AspNetCore.SpaServices.Extensions/StaticFiles/SpaStaticFilesExtensions.cs index 767d997..7036aca 100644 --- a/src/Microsoft.AspNetCore.SpaServices.Extensions/StaticFiles/SpaStaticFilesExtensions.cs +++ b/src/Microsoft.AspNetCore.SpaServices.Extensions/StaticFiles/SpaStaticFilesExtensions.cs @@ -50,53 +50,75 @@ namespace Microsoft.Extensions.DependencyInjection /// /// The . public static void UseSpaStaticFiles(this IApplicationBuilder applicationBuilder) + { + UseSpaStaticFiles(applicationBuilder, new StaticFileOptions()); + } + + /// + /// Configures the application to serve static files for a Single Page Application (SPA). + /// The files will be located using the registered service. + /// + /// The . + /// Specifies options for serving the static files. + public static void UseSpaStaticFiles(this IApplicationBuilder applicationBuilder, StaticFileOptions options) { if (applicationBuilder == null) { throw new ArgumentNullException(nameof(applicationBuilder)); } + if (options == null) + { + throw new ArgumentNullException(nameof(options)); + } + UseSpaStaticFilesInternal(applicationBuilder, - overrideFileProvider: null, + staticFileOptions: options, allowFallbackOnServingWebRootFiles: false); } internal static void UseSpaStaticFilesInternal( this IApplicationBuilder app, - IFileProvider overrideFileProvider, + StaticFileOptions staticFileOptions, bool allowFallbackOnServingWebRootFiles) { - var shouldServeStaticFiles = ShouldServeStaticFiles( - app, - overrideFileProvider, - allowFallbackOnServingWebRootFiles, - out var fileProviderOrDefault); - - if (shouldServeStaticFiles) + if (staticFileOptions == null) { - app.UseStaticFiles(new StaticFileOptions - { - FileProvider = fileProviderOrDefault - }); + throw new ArgumentNullException(nameof(staticFileOptions)); } + + // If the file provider was explicitly supplied, that takes precedence over any other + // configured file provider. This is most useful if the application hosts multiple SPAs + // (via multiple calls to UseSpa()), so each needs to serve its own separate static files + // instead of using AddSpaStaticFiles/UseSpaStaticFiles. + // But if no file provider was specified, try to get one from the DI config. + if (staticFileOptions.FileProvider == null) + { + var shouldServeStaticFiles = ShouldServeStaticFiles( + app, + allowFallbackOnServingWebRootFiles, + out var fileProviderOrDefault); + if (shouldServeStaticFiles) + { + staticFileOptions.FileProvider = fileProviderOrDefault; + } + else + { + // The registered ISpaStaticFileProvider says we shouldn't + // serve static files + return; + } + } + + + app.UseStaticFiles(staticFileOptions); } private static bool ShouldServeStaticFiles( IApplicationBuilder app, - IFileProvider overrideFileProvider, bool allowFallbackOnServingWebRootFiles, out IFileProvider fileProviderOrDefault) { - if (overrideFileProvider != null) - { - // If the file provider was explicitly supplied, that takes precedence over any other - // configured file provider. This is most useful if the application hosts multiple SPAs - // (via multiple calls to UseSpa()), so each needs to serve its own separate static files - // instead of using AddSpaStaticFiles/UseSpaStaticFiles. - fileProviderOrDefault = overrideFileProvider; - return true; - } - var spaStaticFilesService = app.ApplicationServices.GetService(); if (spaStaticFilesService != null) {