diff --git a/src/Components/Blazor/Build/src/ReferenceFromSource.props b/src/Components/Blazor/Build/src/ReferenceFromSource.props
index ca6ee1eb5429..4fef2ec2ceff 100644
--- a/src/Components/Blazor/Build/src/ReferenceFromSource.props
+++ b/src/Components/Blazor/Build/src/ReferenceFromSource.props
@@ -28,7 +28,7 @@
dotnet
<_BlazorCliLocation>$(MSBuildThisFileDirectory)../../DevServer/src/bin/$(Configuration)/netcoreapp3.0/blazor-devserver.dll
- exec "$(_BlazorCliLocation)" serve "$(MSBuildProjectDirectory)/$(OutputPath)$(TargetFileName)" $(AdditionalRunArguments)
+ exec "$(_BlazorCliLocation)" serve --applicationpath "$(MSBuildProjectDirectory)/$(OutputPath)$(TargetFileName)" $(AdditionalRunArguments)
diff --git a/src/Components/Blazor/DevServer/src/Commands/ServeCommand.cs b/src/Components/Blazor/DevServer/src/Commands/ServeCommand.cs
index b30c00d1bd2a..eb7a347051be 100644
--- a/src/Components/Blazor/DevServer/src/Commands/ServeCommand.cs
+++ b/src/Components/Blazor/DevServer/src/Commands/ServeCommand.cs
@@ -1,11 +1,9 @@
// 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 System;
-using System.IO;
-using System.Runtime.Versioning;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.CommandLineUtils;
+using Microsoft.Extensions.Hosting;
namespace Microsoft.AspNetCore.Blazor.DevServer.Commands
{
@@ -23,28 +21,11 @@ public ServeCommand(CommandLineApplication parent)
HelpOption("-?|-h|--help");
- ApplicationPath = new CommandArgument()
- {
- Description = "Path to the client application dll",
- MultipleValues = false,
- Name = "",
- ShowInHelpText = true
- };
- Arguments.Add(ApplicationPath);
-
OnExecute(Execute);
}
- public CommandArgument ApplicationPath { get; private set; }
-
private int Execute()
{
- if (string.IsNullOrWhiteSpace(ApplicationPath.Value))
- {
- throw new InvalidOperationException($"Invalid value for parameter '{nameof(ApplicationPath)}'. Value supplied: '{ApplicationPath.Value}'");
- }
-
- Server.Startup.ApplicationAssembly = ApplicationPath.Value;
Server.Program.BuildWebHost(RemainingArguments.ToArray()).Run();
return 0;
}
diff --git a/src/Components/Blazor/DevServer/src/Microsoft.AspNetCore.Blazor.DevServer.csproj b/src/Components/Blazor/DevServer/src/Microsoft.AspNetCore.Blazor.DevServer.csproj
index ebdf87801f1b..b12f55ef829e 100644
--- a/src/Components/Blazor/DevServer/src/Microsoft.AspNetCore.Blazor.DevServer.csproj
+++ b/src/Components/Blazor/DevServer/src/Microsoft.AspNetCore.Blazor.DevServer.csproj
@@ -19,6 +19,7 @@
+
diff --git a/src/Components/Blazor/DevServer/src/Server/Program.cs b/src/Components/Blazor/DevServer/src/Server/Program.cs
index 55876f5959e3..38f3b0d00526 100644
--- a/src/Components/Blazor/DevServer/src/Server/Program.cs
+++ b/src/Components/Blazor/DevServer/src/Server/Program.cs
@@ -1,8 +1,15 @@
-// Copyright (c) .NET Foundation. All rights reserved.
+// 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 System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Threading;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.Hosting;
namespace Microsoft.AspNetCore.Blazor.DevServer.Server
{
@@ -18,12 +25,24 @@ public class Program
///
/// Intended for framework test use only.
///
- public static IWebHost BuildWebHost(string[] args) =>
- WebHost.CreateDefaultBuilder(args)
- .UseConfiguration(new ConfigurationBuilder()
- .AddCommandLine(args)
- .Build())
- .UseStartup()
- .Build();
+ public static IHost BuildWebHost(string[] args) =>
+ Host.CreateDefaultBuilder(args)
+ .ConfigureHostConfiguration(cb => {
+ var applicationPath = args.SkipWhile(a => a != "--applicationpath").Skip(1).FirstOrDefault();
+ var name = Path.ChangeExtension(applicationPath,".StaticWebAssets.xml");
+
+ if (name != null)
+ {
+ cb.AddInMemoryCollection(new Dictionary
+ {
+ [WebHostDefaults.StaticWebAssetsKey] = name
+ });
+ }
+ })
+ .ConfigureWebHostDefaults(webBuilder =>
+ {
+ webBuilder.UseStaticWebAssets();
+ webBuilder.UseStartup();
+ }).Build();
}
}
diff --git a/src/Components/Blazor/DevServer/src/Server/Startup.cs b/src/Components/Blazor/DevServer/src/Server/Startup.cs
index cb0301aef6b5..95f15ff3e54d 100644
--- a/src/Components/Blazor/DevServer/src/Server/Startup.cs
+++ b/src/Components/Blazor/DevServer/src/Server/Startup.cs
@@ -17,7 +17,12 @@ namespace Microsoft.AspNetCore.Blazor.DevServer.Server
{
internal class Startup
{
- public static string ApplicationAssembly { get; set; }
+ public Startup(IConfiguration configuration)
+ {
+ Configuration = configuration;
+ }
+
+ public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
@@ -35,7 +40,7 @@ public void ConfigureServices(IServiceCollection services)
public void Configure(IApplicationBuilder app, IWebHostEnvironment environment, IConfiguration configuration)
{
- var applicationAssemblyFullPath = ResolveApplicationAssemblyFullPath(environment);
+ var applicationAssemblyFullPath = ResolveApplicationAssemblyFullPath();
app.UseDeveloperExceptionPage();
app.UseResponseCompression();
@@ -54,15 +59,22 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment environment,
});
}
- private static string ResolveApplicationAssemblyFullPath(IWebHostEnvironment environment)
+ private string ResolveApplicationAssemblyFullPath()
{
- var applicationAssemblyFullPath = Path.Combine(environment.ContentRootPath, ApplicationAssembly);
- if (!File.Exists(applicationAssemblyFullPath))
+ const string applicationPathKey = "applicationpath";
+ var configuredApplicationPath = Configuration.GetValue(applicationPathKey);
+ if (string.IsNullOrEmpty(configuredApplicationPath))
+ {
+ throw new InvalidOperationException($"No value was supplied for the required option '{applicationPathKey}'.");
+ }
+
+ var resolvedApplicationPath = Path.GetFullPath(configuredApplicationPath);
+ if (!File.Exists(resolvedApplicationPath))
{
- throw new InvalidOperationException($"Application assembly not found at {applicationAssemblyFullPath}.");
+ throw new InvalidOperationException($"Application assembly not found at {resolvedApplicationPath}.");
}
- return applicationAssemblyFullPath;
+ return resolvedApplicationPath;
}
private static void EnableConfiguredPathbase(IApplicationBuilder app, IConfiguration configuration)
diff --git a/src/Components/Blazor/DevServer/src/build/Microsoft.AspNetCore.Blazor.DevServer.targets b/src/Components/Blazor/DevServer/src/build/Microsoft.AspNetCore.Blazor.DevServer.targets
index b39cb3949e09..2db2b153fbf1 100644
--- a/src/Components/Blazor/DevServer/src/build/Microsoft.AspNetCore.Blazor.DevServer.targets
+++ b/src/Components/Blazor/DevServer/src/build/Microsoft.AspNetCore.Blazor.DevServer.targets
@@ -2,6 +2,6 @@
<_BlazorDevServerDll>$(MSBuildThisFileDirectory)../tools/blazor-devserver.dll
dotnet
- "$(_BlazorDevServerDll)" serve "$(MSBuildProjectDirectory)/$(OutputPath)$(TargetFileName)"
+ "$(_BlazorDevServerDll)" serve --applicationpath "$(MSBuildProjectDirectory)/$(OutputPath)$(TargetFileName)"
diff --git a/src/Components/build.cmd b/src/Components/build.cmd
index 2406296662e9..35fb6cc3a3be 100644
--- a/src/Components/build.cmd
+++ b/src/Components/build.cmd
@@ -1,3 +1,3 @@
@ECHO OFF
SET RepoRoot=%~dp0..\..
-%RepoRoot%\build.cmd -projects %~dp0**\*.*proj %*
+%RepoRoot%\build.cmd -projects %~dp0**\*.*proj "/p:EnforceE2ETestPrerequisites=true" %*
diff --git a/src/Components/build.sh b/src/Components/build.sh
index 7046bb98a0fc..fa8fecd0e01f 100755
--- a/src/Components/build.sh
+++ b/src/Components/build.sh
@@ -4,4 +4,4 @@ set -euo pipefail
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
repo_root="$DIR/../.."
-"$repo_root/build.sh" --projects "$DIR/**/*.*proj" "$@"
+"$repo_root/build.sh" --projects "$DIR/**/*.*proj" "/p:EnforceE2ETestPrerequisites=true" "$@"
diff --git a/src/Components/test/E2ETest/Infrastructure/ServerFixtures/DevHostServerFixture.cs b/src/Components/test/E2ETest/Infrastructure/ServerFixtures/DevHostServerFixture.cs
index 0526e940aeee..897be5dd5d33 100644
--- a/src/Components/test/E2ETest/Infrastructure/ServerFixtures/DevHostServerFixture.cs
+++ b/src/Components/test/E2ETest/Infrastructure/ServerFixtures/DevHostServerFixture.cs
@@ -2,7 +2,13 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.AspNetCore.Hosting;
+using Microsoft.AspNetCore.Hosting.Server;
+using Microsoft.AspNetCore.Http.Features;
+using Microsoft.Extensions.Hosting;
+using System;
using System.Collections.Generic;
+using System.Threading;
+using System.Threading.Tasks;
using DevHostServerProgram = Microsoft.AspNetCore.Blazor.DevServer.Server.Program;
namespace Microsoft.AspNetCore.Components.E2ETest.Infrastructure.ServerFixtures
@@ -22,7 +28,8 @@ protected override IWebHost CreateWebHost()
{
"--urls", "http://127.0.0.1:0",
"--contentroot", ContentRoot,
- "--pathbase", PathBase
+ "--pathbase", PathBase,
+ "--applicationpath", typeof(TProgram).Assembly.Location,
};
if (!string.IsNullOrEmpty(Environment))
@@ -31,7 +38,29 @@ protected override IWebHost CreateWebHost()
args.Add(Environment);
}
- return DevHostServerProgram.BuildWebHost(args.ToArray());
+ return new FakeWebHost(DevHostServerProgram.BuildWebHost(args.ToArray()));
+ }
+
+ private class FakeWebHost : IWebHost
+ {
+ private readonly IHost _realHost;
+
+ public FakeWebHost(IHost realHost)
+ {
+ _realHost = realHost;
+ }
+
+ public IFeatureCollection ServerFeatures => ((IServer)_realHost.Services.GetService(typeof(IServer))).Features;
+
+ public IServiceProvider Services => _realHost.Services;
+
+ public void Dispose() => _realHost.Dispose();
+
+ public void Start() => _realHost.Start();
+
+ public Task StartAsync(CancellationToken cancellationToken = default) => _realHost.StartAsync();
+
+ public Task StopAsync(CancellationToken cancellationToken = default) => _realHost.StopAsync();
}
}
}
diff --git a/src/Components/test/E2ETest/Microsoft.AspNetCore.Components.E2ETests.csproj b/src/Components/test/E2ETest/Microsoft.AspNetCore.Components.E2ETests.csproj
index 477e5d259dd6..f4a5e45eb5f7 100644
--- a/src/Components/test/E2ETest/Microsoft.AspNetCore.Components.E2ETests.csproj
+++ b/src/Components/test/E2ETest/Microsoft.AspNetCore.Components.E2ETests.csproj
@@ -7,10 +7,7 @@
netcoreapp3.0
Components.E2ETests
-
- true
+ true
false
diff --git a/src/Components/test/testassets/BasicTestApp/wwwroot/index.html b/src/Components/test/testassets/BasicTestApp/wwwroot/index.html
index 78540221c380..249622c96e84 100644
--- a/src/Components/test/testassets/BasicTestApp/wwwroot/index.html
+++ b/src/Components/test/testassets/BasicTestApp/wwwroot/index.html
@@ -5,33 +5,39 @@
Basic test app
+
+
+
- Loading...
+ Loading...
+
+
+
-
-
+
- (function () {
- // Load either blazor.webassembly.js or blazor.server.js depending
- // on the hash part of the URL. This is just to give a way for the
- // test runner to make the selection.
- var src = location.hash === '#server'
- ? 'blazor.server.js'
- : 'blazor.webassembly.js';
- document.write('
+
+