Allow explicit configuration of StaticFileOptions in new SPA APIs. Fixes #1424.

This commit is contained in:
Steve Sanderson
2018-01-02 15:44:59 +00:00
parent 814441c933
commit 15d2f5a898
3 changed files with 51 additions and 28 deletions

View File

@@ -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

View File

@@ -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
}
/// <summary>
/// Gets or sets the <see cref="IFileProvider"/> that supplies content
/// Gets or sets the <see cref="StaticFileOptions"/> that supplies content
/// for serving the SPA's default page.
///
/// If not set, a default file provider will read files from the
/// <see cref="IHostingEnvironment.WebRootPath"/>, which by default is
/// the <c>wwwroot</c> directory.
/// </summary>
public IFileProvider DefaultPageFileProvider { get; set; }
public StaticFileOptions DefaultPageStaticFileOptions { get; set; }
/// <summary>
/// Gets or sets the path, relative to the application working directory,

View File

@@ -50,53 +50,75 @@ namespace Microsoft.Extensions.DependencyInjection
/// </summary>
/// <param name="applicationBuilder">The <see cref="IApplicationBuilder"/>.</param>
public static void UseSpaStaticFiles(this IApplicationBuilder applicationBuilder)
{
UseSpaStaticFiles(applicationBuilder, new StaticFileOptions());
}
/// <summary>
/// Configures the application to serve static files for a Single Page Application (SPA).
/// The files will be located using the registered <see cref="ISpaStaticFileProvider"/> service.
/// </summary>
/// <param name="applicationBuilder">The <see cref="IApplicationBuilder"/>.</param>
/// <param name="options">Specifies options for serving the static files.</param>
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));
}
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;
// 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,
bool allowFallbackOnServingWebRootFiles,
out IFileProvider fileProviderOrDefault)
{
var spaStaticFilesService = app.ApplicationServices.GetService<ISpaStaticFileProvider>();
if (spaStaticFilesService != null)
{