Merge branch 'release/3.1' => 'master' (#14249)

This commit is contained in:
Doug Bunting 2019-09-24 08:59:59 -07:00 committed by GitHub
commit 98e4a1ff63
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 140 additions and 44 deletions

View File

@ -25,7 +25,7 @@ This package is an internal implementation of the .NET Core SDK and is not meant
<BaseRuntimeVersionFileName>aspnetcore_base_runtime.version</BaseRuntimeVersionFileName> <BaseRuntimeVersionFileName>aspnetcore_base_runtime.version</BaseRuntimeVersionFileName>
<BaseRuntimeVersionFileOutputPath>$(InstallersOutputPath)$(BaseRuntimeVersionFileName)</BaseRuntimeVersionFileOutputPath> <BaseRuntimeVersionFileOutputPath>$(InstallersOutputPath)$(BaseRuntimeVersionFileName)</BaseRuntimeVersionFileOutputPath>
<!-- NuGet appends target framework to this value. Example: runtimes/win-x64/lib/netcoreapp5.0/ --> <!-- NuGet appends target framework to this value. Example: runtimes/win-x64/lib/netcoreappX.Y/ -->
<BuildOutputTargetFolder>runtimes/$(RuntimeIdentifier)/lib/</BuildOutputTargetFolder> <BuildOutputTargetFolder>runtimes/$(RuntimeIdentifier)/lib/</BuildOutputTargetFolder>
<!-- We still need the native path to these assets though for the RuntimeList.xml manifest --> <!-- We still need the native path to these assets though for the RuntimeList.xml manifest -->
<ManagedAssetsPackagePath>$(BuildOutputTargetFolder)$(DefaultNetCoreTargetFramework)</ManagedAssetsPackagePath> <ManagedAssetsPackagePath>$(BuildOutputTargetFolder)$(DefaultNetCoreTargetFramework)</ManagedAssetsPackagePath>

View File

@ -47,7 +47,8 @@ namespace Microsoft.AspNetCore.Mvc.Analyzers
new DiagnosticDescriptor( new DiagnosticDescriptor(
"MVC1004", "MVC1004",
"Rename model bound parameter.", "Rename model bound parameter.",
"Property on type '{0}' has the same name as parameter '{1}'. This may result in incorrect model binding. Consider renaming the parameter or using a model binding attribute to override the name.", "Property on type '{0}' has the same name as parameter '{1}'. This may result in incorrect model binding. " +
"Consider renaming the parameter or the property to avoid conflicts. If the type '{0}' has a custom type converter or custom model binder, you can suppress this message.",
"Naming", "Naming",
DiagnosticSeverity.Warning, DiagnosticSeverity.Warning,
isEnabledByDefault: true, isEnabledByDefault: true,

View File

@ -89,12 +89,17 @@ namespace Microsoft.AspNetCore.Mvc.Analyzers
return false; return false;
} }
if (SpecifiesModelType(symbolCache, parameter)) if (SpecifiesModelType(in symbolCache, parameter))
{ {
// Ignore parameters that specify a model type. // Ignore parameters that specify a model type.
return false; return false;
} }
if (!IsComplexType(parameter.Type))
{
return false;
}
var parameterName = GetName(symbolCache, parameter); var parameterName = GetName(symbolCache, parameter);
var type = parameter.Type; var type = parameter.Type;
@ -122,6 +127,26 @@ namespace Microsoft.AspNetCore.Mvc.Analyzers
return false; return false;
} }
private static bool IsComplexType(ITypeSymbol type)
{
// This analyzer should not apply to simple types. In MVC, a simple type is any type that has a type converter that returns true for TypeConverter.CanConvertFrom(typeof(string)).
// Unfortunately there isn't a Roslyn way of determining if a TypeConverter exists for a given symbol or if the converter allows string conversions.
// https://github.com/dotnet/corefx/blob/v3.0.0-preview8.19405.3/src/System.ComponentModel.TypeConverter/src/System/ComponentModel/ReflectTypeDescriptionProvider.cs#L103-L141
// provides a list of types that have built-in converters.
// We'll use a simpler heuristic in the analyzer: A type is simple if it's a value type or if it's in the "System.*" namespace hierarchy.
var @namespace = type.ContainingNamespace?.ToString();
if (@namespace != null)
{
// Things in the System.* namespace hierarchy don't count as complex types. This workarounds
// the problem of discovering type converters on types in mscorlib.
return @namespace != "System" &&
!@namespace.StartsWith("System.", StringComparison.Ordinal);
}
return true;
}
internal static string GetName(in SymbolCache symbolCache, ISymbol symbol) internal static string GetName(in SymbolCache symbolCache, ISymbol symbol)
{ {
foreach (var attribute in symbol.GetAttributes(symbolCache.IModelNameProvider)) foreach (var attribute in symbol.GetAttributes(symbolCache.IModelNameProvider))

View File

@ -0,0 +1,9 @@
using System;
namespace Microsoft.AspNetCore.Mvc.Analyzers.TopLevelParameterNameAnalyzerTestFiles
{
public class IsProblematicParameter_ReturnsFalse_ForSimpleTypes
{
public void ActionMethod(DateTime date, DateTime? day, Uri absoluteUri, Version majorRevision, DayOfWeek sunday) { }
}
}

View File

@ -95,6 +95,30 @@ namespace Microsoft.AspNetCore.Mvc.Analyzers
Assert.False(result); Assert.False(result);
} }
// Test for https://github.com/aspnet/AspNetCore/issues/6945
[Fact]
public async Task IsProblematicParameter_ReturnsFalse_ForSimpleTypes()
{
var testName = nameof(IsProblematicParameter_ReturnsFalse_ForSimpleTypes);
var testSource = MvcTestSource.Read(GetType().Name, testName);
var project = DiagnosticProject.Create(GetType().Assembly, new[] { testSource.Source });
var compilation = await project.GetCompilationAsync();
var modelType = compilation.GetTypeByMetadataName($"Microsoft.AspNetCore.Mvc.Analyzers.TopLevelParameterNameAnalyzerTestFiles.{testName}");
var method = (IMethodSymbol)modelType.GetMembers("ActionMethod").First();
Assert.True(TopLevelParameterNameAnalyzer.SymbolCache.TryCreate(compilation, out var symbolCache));
Assert.Collection(
method.Parameters,
p => Assert.False(TopLevelParameterNameAnalyzer.IsProblematicParameter(symbolCache, p)),
p => Assert.False(TopLevelParameterNameAnalyzer.IsProblematicParameter(symbolCache, p)),
p => Assert.False(TopLevelParameterNameAnalyzer.IsProblematicParameter(symbolCache, p)),
p => Assert.False(TopLevelParameterNameAnalyzer.IsProblematicParameter(symbolCache, p)),
p => Assert.False(TopLevelParameterNameAnalyzer.IsProblematicParameter(symbolCache, p)));
}
[Fact] [Fact]
public async Task IsProblematicParameter_IgnoresStaticProperties() public async Task IsProblematicParameter_IgnoresStaticProperties()
{ {

View File

@ -10,7 +10,9 @@
<a class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Manage/Index" title="Manage">Hello @User.Identity.Name!</a> <a class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Manage/Index" title="Manage">Hello @User.Identity.Name!</a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link text-dark" asp-area="Identity" asp-page="/Account/LogOut">Logout</a> <form class="form-inline" asp-area="Identity" asp-page="/Account/Logout" asp-route-returnUrl="/" method="post">
<button type="submit" class="nav-link btn btn-link text-dark">Logout</button>
</form>
</li> </li>
} }
else else

View File

@ -8,7 +8,7 @@
], ],
"name": "ASP.NET Core Web App", "name": "ASP.NET Core Web App",
"generatorVersions": "[1.0.0.0-*)", "generatorVersions": "[1.0.0.0-*)",
"description": "A project template for creating an ASP.NET Core application with example ASP.NET Razor Pages content", "description": "A project template for creating an ASP.NET Core application with example ASP.NET Core Razor Pages content",
"groupIdentity": "Microsoft.Web.RazorPages", "groupIdentity": "Microsoft.Web.RazorPages",
"precedence": "5000", "precedence": "5000",
"identity": "Microsoft.Web.RazorPages.CSharp.3.0", "identity": "Microsoft.Web.RazorPages.CSharp.3.0",

View File

@ -36,7 +36,7 @@ namespace Templates.Test
Assert.True(0 == publishResult.ExitCode, ErrorMessages.GetFailedProcessMessage("publish", Project, publishResult)); Assert.True(0 == publishResult.ExitCode, ErrorMessages.GetFailedProcessMessage("publish", Project, publishResult));
// Run dotnet build after publish. The reason is that one uses Config = Debug and the other uses Config = Release // Run dotnet build after publish. The reason is that one uses Config = Debug and the other uses Config = Release
// The output from publish will go into bin/Release/netcoreapp5.0/publish and won't be affected by calling build // The output from publish will go into bin/Release/netcoreappX.Y/publish and won't be affected by calling build
// later, while the opposite is not true. // later, while the opposite is not true.
var buildResult = await Project.RunDotNetBuildAsync(); var buildResult = await Project.RunDotNetBuildAsync();
@ -93,7 +93,7 @@ namespace Templates.Test
Assert.True(0 == publishResult.ExitCode, ErrorMessages.GetFailedProcessMessage("publish", Project, publishResult)); Assert.True(0 == publishResult.ExitCode, ErrorMessages.GetFailedProcessMessage("publish", Project, publishResult));
// Run dotnet build after publish. The reason is that one uses Config = Debug and the other uses Config = Release // Run dotnet build after publish. The reason is that one uses Config = Debug and the other uses Config = Release
// The output from publish will go into bin/Release/netcoreapp5.0/publish and won't be affected by calling build // The output from publish will go into bin/Release/netcoreappX.Y/publish and won't be affected by calling build
// later, while the opposite is not true. // later, while the opposite is not true.
var buildResult = await Project.RunDotNetBuildAsync(); var buildResult = await Project.RunDotNetBuildAsync();

View File

@ -22,10 +22,19 @@ namespace Templates.Test
public ITestOutputHelper Output { get; } public ITestOutputHelper Output { get; }
[Theory] [Fact]
[InlineData(null)] public async Task EmptyWebTemplateCSharp()
[InlineData("F#")] {
public async Task EmptyWebTemplateAsync(string languageOverride) await EmtpyTemplateCore(languageOverride: null);
}
[Fact]
public async Task EmptyWebTemplateFSharp()
{
await EmtpyTemplateCore("F#");
}
private async Task EmtpyTemplateCore(string languageOverride)
{ {
Project = await ProjectFactory.GetOrCreateProject("empty" + (languageOverride == "F#" ? "fsharp" : "csharp"), Output); Project = await ProjectFactory.GetOrCreateProject("empty" + (languageOverride == "F#" ? "fsharp" : "csharp"), Output);
@ -42,7 +51,7 @@ namespace Templates.Test
Assert.True(0 == publishResult.ExitCode, ErrorMessages.GetFailedProcessMessage("publish", Project, publishResult)); Assert.True(0 == publishResult.ExitCode, ErrorMessages.GetFailedProcessMessage("publish", Project, publishResult));
// Run dotnet build after publish. The reason is that one uses Config = Debug and the other uses Config = Release // Run dotnet build after publish. The reason is that one uses Config = Debug and the other uses Config = Release
// The output from publish will go into bin/Release/netcoreapp5.0/publish and won't be affected by calling build // The output from publish will go into bin/Release/netcoreappX.Y/publish and won't be affected by calling build
// later, while the opposite is not true. // later, while the opposite is not true.
var buildResult = await Project.RunDotNetBuildAsync(); var buildResult = await Project.RunDotNetBuildAsync();

View File

@ -58,7 +58,7 @@ namespace Templates.Test.Helpers
var arguments = published ? $"exec {dllPath}" : "run"; var arguments = published ? $"exec {dllPath}" : "run";
Process = ProcessEx.Run(output, workingDirectory, DotNetMuxer.MuxerPathOrDefault(), arguments, envVars: environmentVariables); Process = ProcessEx.Run(output, workingDirectory, DotNetMuxer.MuxerPathOrDefault(), arguments, envVars: environmentVariables);
if(hasListeningUri) if (hasListeningUri)
{ {
ListeningUri = GetListeningUri(output); ListeningUri = GetListeningUri(output);
} }
@ -108,7 +108,7 @@ namespace Templates.Test.Helpers
HttpMethod.Get, HttpMethod.Get,
new Uri(ListeningUri, page.Url)); new Uri(ListeningUri, page.Url));
var response = await _httpClient.SendAsync(request); var response = await RequestWithRetries(client => client.SendAsync(request), _httpClient);
Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var parser = new HtmlParser(); var parser = new HtmlParser();
@ -141,7 +141,7 @@ namespace Templates.Test.Helpers
Assert.True(string.Equals(anchor.Href, expectedLink), $"Expected next link to be {expectedLink} but it was {anchor.Href}."); Assert.True(string.Equals(anchor.Href, expectedLink), $"Expected next link to be {expectedLink} but it was {anchor.Href}.");
var result = await RetryHelper.RetryRequest(async () => var result = await RetryHelper.RetryRequest(async () =>
{ {
return await _httpClient.GetAsync(anchor.Href); return await RequestWithRetries(client => client.GetAsync(anchor.Href), _httpClient);
}, logger: NullLogger.Instance); }, logger: NullLogger.Instance);
Assert.True(IsSuccessStatusCode(result), $"{anchor.Href} is a broken link!"); Assert.True(IsSuccessStatusCode(result), $"{anchor.Href} is a broken link!");
@ -149,6 +149,28 @@ namespace Templates.Test.Helpers
} }
} }
private async Task<T> RequestWithRetries<T>(Func<HttpClient, Task<T>> requester, HttpClient client, int retries = 3, TimeSpan initialDelay = default)
{
var currentDelay = initialDelay == default ? TimeSpan.FromSeconds(30) : initialDelay;
for (int i = 0; i <= retries; i++)
{
try
{
return await requester(client);
}
catch (Exception)
{
if (i == retries)
{
throw;
}
await Task.Delay(currentDelay);
currentDelay *= 2;
}
}
throw new InvalidOperationException("Max retries reached.");
}
private Uri GetListeningUri(ITestOutputHelper output) private Uri GetListeningUri(ITestOutputHelper output)
{ {
// Wait until the app is accepting HTTP requests // Wait until the app is accepting HTTP requests
@ -190,7 +212,7 @@ namespace Templates.Test.Helpers
internal Task<HttpResponseMessage> SendRequest(string path) internal Task<HttpResponseMessage> SendRequest(string path)
{ {
return _httpClient.GetAsync(new Uri(ListeningUri, path)); return RequestWithRetries(client => client.GetAsync(new Uri(ListeningUri, path)), _httpClient);
} }
public async Task AssertStatusCode(string requestUrl, HttpStatusCode statusCode, string acceptContentType = null) public async Task AssertStatusCode(string requestUrl, HttpStatusCode statusCode, string acceptContentType = null)
@ -204,7 +226,7 @@ namespace Templates.Test.Helpers
request.Headers.Add("Accept", acceptContentType); request.Headers.Add("Accept", acceptContentType);
} }
var response = await _httpClient.SendAsync(request); var response = await RequestWithRetries(client => client.SendAsync(request), _httpClient);
Assert.True(statusCode == response.StatusCode, $"Expected {requestUrl} to have status '{statusCode}' but it was '{response.StatusCode}'."); Assert.True(statusCode == response.StatusCode, $"Expected {requestUrl} to have status '{statusCode}' but it was '{response.StatusCode}'.");
} }

View File

@ -134,7 +134,7 @@ namespace Templates.Test
Assert.True(0 == publishResult.ExitCode, ErrorMessages.GetFailedProcessMessage("publish", Project, publishResult)); Assert.True(0 == publishResult.ExitCode, ErrorMessages.GetFailedProcessMessage("publish", Project, publishResult));
// Run dotnet build after publish. The reason is that one uses Config = Debug and the other uses Config = Release // Run dotnet build after publish. The reason is that one uses Config = Debug and the other uses Config = Release
// The output from publish will go into bin/Release/netcoreapp5.0/publish and won't be affected by calling build // The output from publish will go into bin/Release/netcoreappX.Y/publish and won't be affected by calling build
// later, while the opposite is not true. // later, while the opposite is not true.
var buildResult = await Project.RunDotNetBuildAsync(packageOptions: packageOptions); var buildResult = await Project.RunDotNetBuildAsync(packageOptions: packageOptions);

View File

@ -25,11 +25,14 @@ namespace Templates.Test
public ProjectFactoryFixture ProjectFactory { get; } public ProjectFactoryFixture ProjectFactory { get; }
public ITestOutputHelper Output { get; } public ITestOutputHelper Output { get; }
[Theory] [Fact(Skip = "https://github.com/aspnet/AspNetCore/issues/14022")]
[InlineData(null)] public async Task MvcTemplate_NoAuthFSharp() => await MvcTemplateCore(languageOverride: "F#");
[InlineData("F#")]
[Flaky("https://github.com/aspnet/AspNetCore-Internal/issues/2267", FlakyOn.All)] [Fact]
public async Task MvcTemplate_NoAuthImplAsync(string languageOverride) public async Task MvcTemplate_NoAuthCSharp() => await MvcTemplateCore(languageOverride: null);
private async Task MvcTemplateCore(string languageOverride)
{ {
Project = await ProjectFactory.GetOrCreateProject("mvcnoauth" + (languageOverride == "F#" ? "fsharp" : "csharp"), Output); Project = await ProjectFactory.GetOrCreateProject("mvcnoauth" + (languageOverride == "F#" ? "fsharp" : "csharp"), Output);
@ -54,7 +57,7 @@ namespace Templates.Test
Assert.True(0 == publishResult.ExitCode, ErrorMessages.GetFailedProcessMessage("publish", Project, publishResult)); Assert.True(0 == publishResult.ExitCode, ErrorMessages.GetFailedProcessMessage("publish", Project, publishResult));
// Run dotnet build after publish. The reason is that one uses Config = Debug and the other uses Config = Release // Run dotnet build after publish. The reason is that one uses Config = Debug and the other uses Config = Release
// The output from publish will go into bin/Release/netcoreapp5.0/publish and won't be affected by calling build // The output from publish will go into bin/Release/netcoreappX.Y/publish and won't be affected by calling build
// later, while the opposite is not true. // later, while the opposite is not true.
var buildResult = await Project.RunDotNetBuildAsync(); var buildResult = await Project.RunDotNetBuildAsync();
@ -104,8 +107,7 @@ namespace Templates.Test
[Theory] [Theory]
[InlineData(true)] [InlineData(true)]
[InlineData(false)] [InlineData(false)]
[Flaky("https://github.com/aspnet/AspNetCore-Internal/issues/2267", FlakyOn.All)] public async Task MvcTemplate_IndividualAuth(bool useLocalDB)
public async Task MvcTemplate_IndividualAuthImplAsync(bool useLocalDB)
{ {
Project = await ProjectFactory.GetOrCreateProject("mvcindividual" + (useLocalDB ? "uld" : ""), Output); Project = await ProjectFactory.GetOrCreateProject("mvcindividual" + (useLocalDB ? "uld" : ""), Output);
@ -122,7 +124,7 @@ namespace Templates.Test
Assert.True(0 == publishResult.ExitCode, ErrorMessages.GetFailedProcessMessage("publish", Project, publishResult)); Assert.True(0 == publishResult.ExitCode, ErrorMessages.GetFailedProcessMessage("publish", Project, publishResult));
// Run dotnet build after publish. The reason is that one uses Config = Debug and the other uses Config = Release // Run dotnet build after publish. The reason is that one uses Config = Debug and the other uses Config = Release
// The output from publish will go into bin/Release/netcoreapp5.0/publish and won't be affected by calling build // The output from publish will go into bin/Release/netcoreappX.Y/publish and won't be affected by calling build
// later, while the opposite is not true. // later, while the opposite is not true.
var buildResult = await Project.RunDotNetBuildAsync(); var buildResult = await Project.RunDotNetBuildAsync();

View File

@ -33,7 +33,7 @@ namespace Templates.Test
Assert.True(0 == publishResult.ExitCode, ErrorMessages.GetFailedProcessMessage("publish", Project, publishResult)); Assert.True(0 == publishResult.ExitCode, ErrorMessages.GetFailedProcessMessage("publish", Project, publishResult));
// Run dotnet build after publish. The reason is that one uses Config = Debug and the other uses Config = Release // Run dotnet build after publish. The reason is that one uses Config = Debug and the other uses Config = Release
// The output from publish will go into bin/Release/netcoreapp5.0/publish and won't be affected by calling build // The output from publish will go into bin/Release/netcoreappX.Y/publish and won't be affected by calling build
// later, while the opposite is not true. // later, while the opposite is not true.
var buildResult = await Project.RunDotNetBuildAsync(); var buildResult = await Project.RunDotNetBuildAsync();
@ -52,7 +52,7 @@ namespace Templates.Test
Assert.True(0 == publishResult.ExitCode, ErrorMessages.GetFailedProcessMessage("publish", Project, publishResult)); Assert.True(0 == publishResult.ExitCode, ErrorMessages.GetFailedProcessMessage("publish", Project, publishResult));
// Run dotnet build after publish. The reason is that one uses Config = Debug and the other uses Config = Release // Run dotnet build after publish. The reason is that one uses Config = Debug and the other uses Config = Release
// The output from publish will go into bin/Release/netcoreapp5.0/publish and won't be affected by calling build // The output from publish will go into bin/Release/netcoreappX.Y/publish and won't be affected by calling build
// later, while the opposite is not true. // later, while the opposite is not true.
var buildResult = await Project.RunDotNetBuildAsync(); var buildResult = await Project.RunDotNetBuildAsync();

View File

@ -26,8 +26,7 @@ namespace Templates.Test
public ITestOutputHelper Output { get; } public ITestOutputHelper Output { get; }
[Fact] [Fact]
[Flaky("https://github.com/aspnet/AspNetCore-Internal/issues/2327", FlakyOn.All)] public async Task RazorPagesTemplate_NoAuth()
public async Task RazorPagesTemplate_NoAuthImplAsync()
{ {
Project = await ProjectFactory.GetOrCreateProject("razorpagesnoauth", Output); Project = await ProjectFactory.GetOrCreateProject("razorpagesnoauth", Output);
@ -45,7 +44,7 @@ namespace Templates.Test
Assert.True(0 == publishResult.ExitCode, ErrorMessages.GetFailedProcessMessage("publish", Project, createResult)); Assert.True(0 == publishResult.ExitCode, ErrorMessages.GetFailedProcessMessage("publish", Project, createResult));
// Run dotnet build after publish. The reason is that one uses Config = Debug and the other uses Config = Release // Run dotnet build after publish. The reason is that one uses Config = Debug and the other uses Config = Release
// The output from publish will go into bin/Release/netcoreapp5.0/publish and won't be affected by calling build // The output from publish will go into bin/Release/netcoreappX.Y/publish and won't be affected by calling build
// later, while the opposite is not true. // later, while the opposite is not true.
var buildResult = await Project.RunDotNetBuildAsync(); var buildResult = await Project.RunDotNetBuildAsync();
@ -95,10 +94,9 @@ namespace Templates.Test
} }
[Theory] [Theory]
[Flaky("https://github.com/aspnet/AspNetCore-Internal/issues/2335", FlakyOn.All)]
[InlineData(false)] [InlineData(false)]
[InlineData(true)] [InlineData(true)]
public async Task RazorPagesTemplate_IndividualAuthImplAsync(bool useLocalDB) public async Task RazorPagesTemplate_IndividualAuth(bool useLocalDB)
{ {
Project = await ProjectFactory.GetOrCreateProject("razorpagesindividual" + (useLocalDB ? "uld" : ""), Output); Project = await ProjectFactory.GetOrCreateProject("razorpagesindividual" + (useLocalDB ? "uld" : ""), Output);
@ -115,7 +113,7 @@ namespace Templates.Test
Assert.True(0 == publishResult.ExitCode, ErrorMessages.GetFailedProcessMessage("publish", Project, publishResult)); Assert.True(0 == publishResult.ExitCode, ErrorMessages.GetFailedProcessMessage("publish", Project, publishResult));
// Run dotnet build after publish. The reason is that one uses Config = Debug and the other uses Config = Release // Run dotnet build after publish. The reason is that one uses Config = Debug and the other uses Config = Release
// The output from publish will go into bin/Release/netcoreapp5.0/publish and won't be affected by calling build // The output from publish will go into bin/Release/netcoreappX.Y/publish and won't be affected by calling build
// later, while the opposite is not true. // later, while the opposite is not true.
var buildResult = await Project.RunDotNetBuildAsync(); var buildResult = await Project.RunDotNetBuildAsync();

View File

@ -74,7 +74,7 @@ namespace Templates.Test.SpaTemplateTest
Assert.True(0 == publishResult.ExitCode, ErrorMessages.GetFailedProcessMessage("publish", Project, publishResult)); Assert.True(0 == publishResult.ExitCode, ErrorMessages.GetFailedProcessMessage("publish", Project, publishResult));
// Run dotnet build after publish. The reason is that one uses Config = Debug and the other uses Config = Release // Run dotnet build after publish. The reason is that one uses Config = Debug and the other uses Config = Release
// The output from publish will go into bin/Release/netcoreapp5.0/publish and won't be affected by calling build // The output from publish will go into bin/Release/netcoreappX.Y/publish and won't be affected by calling build
// later, while the opposite is not true. // later, while the opposite is not true.
using var buildResult = await Project.RunDotNetBuildAsync(); using var buildResult = await Project.RunDotNetBuildAsync();

View File

@ -22,10 +22,13 @@ namespace Templates.Test
public Project Project { get; set; } public Project Project { get; set; }
[Theory] [Fact]
[InlineData(null)] public async Task WebApiTemplateFSharp() => await WebApiTemplateCore(languageOverride: "F#");
[InlineData("F#")]
public async Task WebApiTemplateAsync(string languageOverride) [Fact]
public async Task WebApiTemplateCSharp() => await WebApiTemplateCore(languageOverride: null);
private async Task WebApiTemplateCore(string languageOverride)
{ {
Project = await FactoryFixture.GetOrCreateProject("webapi" + (languageOverride == "F#" ? "fsharp" : "csharp"), Output); Project = await FactoryFixture.GetOrCreateProject("webapi" + (languageOverride == "F#" ? "fsharp" : "csharp"), Output);
@ -42,7 +45,7 @@ namespace Templates.Test
Assert.True(0 == publishResult.ExitCode, ErrorMessages.GetFailedProcessMessage("publish", Project, publishResult)); Assert.True(0 == publishResult.ExitCode, ErrorMessages.GetFailedProcessMessage("publish", Project, publishResult));
// Run dotnet build after publish. The reason is that one uses Config = Debug and the other uses Config = Release // Run dotnet build after publish. The reason is that one uses Config = Debug and the other uses Config = Release
// The output from publish will go into bin/Release/netcoreapp5.0/publish and won't be affected by calling build // The output from publish will go into bin/Release/netcoreappX.Y/publish and won't be affected by calling build
// later, while the opposite is not true. // later, while the opposite is not true.
var buildResult = await Project.RunDotNetBuildAsync(); var buildResult = await Project.RunDotNetBuildAsync();

View File

@ -32,7 +32,7 @@ namespace Templates.Test
Assert.True(0 == publishResult.ExitCode, ErrorMessages.GetFailedProcessMessage("publish", Project, publishResult)); Assert.True(0 == publishResult.ExitCode, ErrorMessages.GetFailedProcessMessage("publish", Project, publishResult));
// Run dotnet build after publish. The reason is that one uses Config = Debug and the other uses Config = Release // Run dotnet build after publish. The reason is that one uses Config = Debug and the other uses Config = Release
// The output from publish will go into bin/Release/netcoreapp5.0/publish and won't be affected by calling build // The output from publish will go into bin/Release/netcoreappX.Y/publish and won't be affected by calling build
// later, while the opposite is not true. // later, while the opposite is not true.
var buildResult = await Project.RunDotNetBuildAsync(); var buildResult = await Project.RunDotNetBuildAsync();

View File

@ -51,7 +51,7 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting.IIS
// Start timer // Start timer
StartTimer(); StartTimer();
// For an unpublished application the dllroot points pre-built dlls like projectdir/bin/debug/netcoreapp5.0/ // For an unpublished application the dllroot points pre-built dlls like projectdir/bin/debug/netcoreappX.Y/
// and contentRoot points to the project directory so you get things like static assets. // and contentRoot points to the project directory so you get things like static assets.
// For a published app both point to the publish directory. // For a published app both point to the publish directory.
var dllRoot = CheckIfPublishIsRequired(); var dllRoot = CheckIfPublishIsRequired();

View File

@ -155,7 +155,8 @@ namespace Microsoft.AspNetCore.Http.Connections.Internal.Transports
var memory = _application.Output.GetMemory(); var memory = _application.Output.GetMemory();
var receiveResult = await socket.ReceiveAsync(memory, token); var receiveResult = await socket.ReceiveAsync(memory, token);
// Need to check again for netcoreapp5.0 because a close can happen between a 0-byte read and the actual read
// Need to check again for netcoreapp3.0 and later because a close can happen between a 0-byte read and the actual read
if (receiveResult.MessageType == WebSocketMessageType.Close) if (receiveResult.MessageType == WebSocketMessageType.Close)
{ {
return; return;