Skip to content

[automated] Merge branch 'release/5.0-preview8' => 'master' #24258

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ public async Task BuildMinimal_Works()
// Arrange
// Minimal has no project references, service worker etc. This is pretty close to the project template.
using var project = ProjectDirectory.Create("blazorwasm-minimal");
File.WriteAllText(Path.Combine(project.DirectoryPath, "App.razor.css"), "h1 { font-size: 16px; }");

var result = await MSBuildProcessManager.DotnetMSBuild(project);

Assert.BuildPassed(result);
Expand All @@ -35,6 +37,7 @@ public async Task BuildMinimal_Works()

var staticWebAssets = Assert.FileExists(result, buildOutputDirectory, "blazorwasm-minimal.StaticWebAssets.xml");
Assert.FileContains(result, staticWebAssets, Path.Combine(project.TargetFramework, "wwwroot"));
Assert.FileContains(result, staticWebAssets, Path.Combine(project.TargetFramework, "scopedcss"));
}

[Fact]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,58 @@ public async Task Publish_WithDefaultSettings_Works()
VerifyTypeGranularTrimming(result, blazorPublishDirectory);
}

[Fact]
public async Task Publish_WithScopedCss_Works()
{
// Arrange
using var project = ProjectDirectory.Create("blazorwasm", additionalProjects: new[] { "razorclasslibrary", "LinkBaseToWebRoot" });
File.WriteAllText(Path.Combine(project.DirectoryPath, "App.razor.css"), "h1 { font-size: 16px; }");

project.Configuration = "Debug";
var result = await MSBuildProcessManager.DotnetMSBuild(project, "Publish");

Assert.BuildPassed(result);

var publishDirectory = project.PublishOutputDirectory;

var blazorPublishDirectory = Path.Combine(publishDirectory, "wwwroot");

Assert.FileExists(result, blazorPublishDirectory, "_framework", "blazor.boot.json");
Assert.FileExists(result, blazorPublishDirectory, "_framework", "blazor.webassembly.js");
Assert.FileExists(result, blazorPublishDirectory, "_framework", "dotnet.wasm");
Assert.FileExists(result, blazorPublishDirectory, "_framework", DotNetJsFileName);
Assert.FileExists(result, blazorPublishDirectory, "_framework", "blazorwasm.dll");
Assert.FileExists(result, blazorPublishDirectory, "_framework", "System.Text.Json.dll"); // Verify dependencies are part of the output.

// Verify scoped css
Assert.FileExists(result, blazorPublishDirectory, "_framework", "scoped.styles.css");

// Verify referenced static web assets
Assert.FileExists(result, blazorPublishDirectory, "_content", "RazorClassLibrary", "wwwroot", "exampleJsInterop.js");
Assert.FileExists(result, blazorPublishDirectory, "_content", "RazorClassLibrary", "styles.css");

// Verify static assets are in the publish directory
Assert.FileExists(result, blazorPublishDirectory, "index.html");

// Verify link item assets are in the publish directory
Assert.FileExists(result, blazorPublishDirectory, "js", "LinkedScript.js");
var cssFile = Assert.FileExists(result, blazorPublishDirectory, "css", "app.css");
Assert.FileContains(result, cssFile, ".publish");
Assert.FileDoesNotExist(result, "dist", "Fake-License.txt");

// Verify web.config
Assert.FileExists(result, publishDirectory, "web.config");
Assert.FileCountEquals(result, 1, publishDirectory, "*", SearchOption.TopDirectoryOnly);

VerifyBootManifestHashes(result, blazorPublishDirectory);
VerifyServiceWorkerFiles(result, blazorPublishDirectory,
serviceWorkerPath: Path.Combine("serviceworkers", "my-service-worker.js"),
serviceWorkerContent: "// This is the production service worker",
assetsManifestPath: "custom-service-worker-assets.js");

VerifyTypeGranularTrimming(result, blazorPublishDirectory);
}

[Fact]
public async Task Publish_InRelease_Works()
{
Expand Down Expand Up @@ -578,6 +630,58 @@ public async Task Publish_HostedApp_VisualStudio()
assetsManifestPath: "custom-service-worker-assets.js");
}

[Fact]
public async Task Publish_HostedAppWithScopedCss_VisualStudio()
{
// Simulates publishing the same way VS does by setting BuildProjectReferences=false.
// Arrange
using var project = ProjectDirectory.Create("blazorhosted", additionalProjects: new[] { "blazorwasm", "razorclasslibrary", });
File.WriteAllText(Path.Combine(project.SolutionPath, "blazorwasm", "App.razor.css"), "h1 { font-size: 16px; }");

project.Configuration = "Release";
var result = await MSBuildProcessManager.DotnetMSBuild(project, "Build", "/p:BuildInsideVisualStudio=true");

Assert.BuildPassed(result);

result = await MSBuildProcessManager.DotnetMSBuild(project, "Publish", "/p:BuildProjectReferences=false /p:BuildInsideVisualStudio=true");

var publishDirectory = project.PublishOutputDirectory;
// Make sure the main project exists
Assert.FileExists(result, publishDirectory, "blazorhosted.dll");

var blazorPublishDirectory = Path.Combine(publishDirectory, "wwwroot");
Assert.FileExists(result, blazorPublishDirectory, "_framework", "blazor.boot.json");
Assert.FileExists(result, blazorPublishDirectory, "_framework", "dotnet.wasm");
Assert.FileExists(result, blazorPublishDirectory, "_framework", DotNetJsFileName);
Assert.FileExists(result, blazorPublishDirectory, "_framework", "blazorwasm.dll");
Assert.FileExists(result, blazorPublishDirectory, "_framework", "System.Text.Json.dll"); // Verify dependencies are part of the output.

// Verify scoped css
Assert.FileExists(result, blazorPublishDirectory, "_framework", "scoped.styles.css");

// Verify static assets are in the publish directory
Assert.FileExists(result, blazorPublishDirectory, "index.html");

// Verify static web assets from referenced projects are copied.
Assert.FileExists(result, publishDirectory, "wwwroot", "_content", "RazorClassLibrary", "wwwroot", "exampleJsInterop.js");
Assert.FileExists(result, publishDirectory, "wwwroot", "_content", "RazorClassLibrary", "styles.css");

// Verify compression works
Assert.FileExists(result, blazorPublishDirectory, "_framework", "dotnet.wasm.br");
Assert.FileExists(result, blazorPublishDirectory, "_framework", "blazorwasm.dll.br");
Assert.FileExists(result, blazorPublishDirectory, "_framework", "RazorClassLibrary.dll.br");
Assert.FileExists(result, blazorPublishDirectory, "_framework", "System.Text.Json.dll.br");

// Verify web.config
Assert.FileExists(result, publishDirectory, "web.config");

VerifyBootManifestHashes(result, blazorPublishDirectory);
VerifyServiceWorkerFiles(result, blazorPublishDirectory,
serviceWorkerPath: Path.Combine("serviceworkers", "my-service-worker.js"),
serviceWorkerContent: "// This is the production service worker",
assetsManifestPath: "custom-service-worker-assets.js");
}

// Regression test to verify satellite assemblies from the blazor app are copied to the published app's wwwroot output directory as
// part of publishing in VS
[Fact]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,7 @@ Copyright (c) .NET Foundation. All rights reserved.

<GetCurrentProjectStaticWebAssetsDependsOn>
$(GetCurrentProjectStaticWebAssetsDependsOn);
AddScopedCssBundle;
_BlazorWasmPrepareForRun;
</GetCurrentProjectStaticWebAssetsDependsOn>
</PropertyGroup>
Expand Down
30 changes: 0 additions & 30 deletions src/Identity/Core/src/IdentityServiceCollectionExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -110,21 +110,6 @@ public static IdentityBuilder AddIdentity<TUser, TRole>(
public static IServiceCollection ConfigureApplicationCookie(this IServiceCollection services, Action<CookieAuthenticationOptions> configure)
=> services.Configure(IdentityConstants.ApplicationScheme, configure);

/// <summary>
/// Configures the application cookie.
/// </summary>
/// <typeparam name="TService">TService: A service resolved from the IServiceProvider for use when configuring this authentication provider. If you need multiple services then specify IServiceProvider and resolve them directly.</typeparam>
/// <param name="services">The services available in the application.</param>
/// <param name="configure">An action to configure the <see cref="CookieAuthenticationOptions"/>.</param>
/// <returns>The services.</returns>
public static IServiceCollection ConfigureApplicationCookie<TService>(this IServiceCollection services, Action<CookieAuthenticationOptions, TService> configure) where TService : class
{
services.AddOptions<CookieAuthenticationOptions>(IdentityConstants.ApplicationScheme)
.Configure(configure);

return services;
}

/// <summary>
/// Configure the external cookie.
/// </summary>
Expand All @@ -133,20 +118,5 @@ public static IServiceCollection ConfigureApplicationCookie<TService>(this IServ
/// <returns>The services.</returns>
public static IServiceCollection ConfigureExternalCookie(this IServiceCollection services, Action<CookieAuthenticationOptions> configure)
=> services.Configure(IdentityConstants.ExternalScheme, configure);

/// <summary>
/// Configure the external cookie.
/// </summary>
/// <typeparam name="TService">TService: A service resolved from the IServiceProvider for use when configuring this authentication provider. If you need multiple services then specify IServiceProvider and resolve them directly.</typeparam>
/// <param name="services">The services available in the application.</param>
/// <param name="configure">An action to configure the <see cref="CookieAuthenticationOptions"/>.</param>
/// <returns>The services.</returns>
public static IServiceCollection ConfigureExternalCookie<TService>(this IServiceCollection services, Action<CookieAuthenticationOptions, TService> configure) where TService : class
{
services.AddOptions<CookieAuthenticationOptions>(IdentityConstants.ExternalScheme)
.Configure(configure);

return services;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,17 @@
namespace Microsoft.AspNetCore.Mvc.ModelBinding
{
/// <summary>
/// Provides a predicate which can determines which model properties should be bound by model binding.
/// Provides a predicate which can determines which model properties or parameters should be bound by model binding.
/// </summary>
public interface IPropertyFilterProvider
{
/// <summary>
/// <para>
/// Gets a predicate which can determines which model properties should be bound by model binding.
/// </para>
/// <para>
/// This predicate is also used to determine which parameters are bound when a model's constructor is bound.
/// </para>
/// </summary>
Func<ModelMetadata, bool> PropertyFilter { get; }
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public abstract class ModelBindingMessageProvider
/// <summary>
/// Error message the model binding system adds when <see cref="ModelError.Exception"/> is of type
/// <see cref="FormatException"/> or <see cref="OverflowException"/>, value is known, and error is associated
/// with a collection element or action parameter.
/// with a collection element or parameter.
/// </summary>
/// <value>Default <see cref="string"/> is "The value '{0}' is not valid.".</value>
public virtual Func<string, string> NonPropertyAttemptedValueIsInvalidAccessor { get; } = default!;
Expand All @@ -67,7 +67,7 @@ public abstract class ModelBindingMessageProvider
/// <summary>
/// Error message the model binding system adds when <see cref="ModelError.Exception"/> is of type
/// <see cref="FormatException"/> or <see cref="OverflowException"/>, value is unknown, and error is associated
/// with a collection element or action parameter.
/// with a collection element or parameter.
/// </summary>
/// <value>Default <see cref="string"/> is "The supplied value is invalid.".</value>
public virtual Func<string> NonPropertyUnknownValueIsInvalidAccessor { get; } = default!;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,14 @@ private ModelMetadataIdentity(
Type modelType,
string? name = null,
Type? containerType = null,
object? fieldInfo = null)
object? fieldInfo = null,
ConstructorInfo? constructorInfo = null)
{
ModelType = modelType;
Name = name;
ContainerType = containerType;
FieldInfo = fieldInfo;
ConstructorInfo = constructorInfo;
}

/// <summary>
Expand Down Expand Up @@ -130,6 +132,28 @@ public static ModelMetadataIdentity ForParameter(ParameterInfo parameter, Type m
return new ModelMetadataIdentity(modelType, parameter.Name, fieldInfo: parameter);
}

/// <summary>
/// Creates a <see cref="ModelMetadataIdentity"/> for the provided parameter with the specified
/// model type.
/// </summary>
/// <param name="constructor">The <see cref="ConstructorInfo" />.</param>
/// <param name="modelType">The model type.</param>
/// <returns>A <see cref="ModelMetadataIdentity"/>.</returns>
public static ModelMetadataIdentity ForConstructor(ConstructorInfo constructor, Type modelType)
{
if (constructor == null)
{
throw new ArgumentNullException(nameof(constructor));
}

if (modelType == null)
{
throw new ArgumentNullException(nameof(modelType));
}

return new ModelMetadataIdentity(modelType, constructor.Name, constructorInfo: constructor);
}

/// <summary>
/// Gets the <see cref="Type"/> defining the model property represented by the current
/// instance, or <c>null</c> if the current instance does not represent a property.
Expand All @@ -152,6 +176,10 @@ public ModelMetadataKind MetadataKind
{
return ModelMetadataKind.Parameter;
}
else if (ConstructorInfo != null)
{
return ModelMetadataKind.Constructor;
}
else if (ContainerType != null && Name != null)
{
return ModelMetadataKind.Property;
Expand Down Expand Up @@ -183,6 +211,12 @@ public ModelMetadataKind MetadataKind
/// </summary>
public PropertyInfo? PropertyInfo => FieldInfo as PropertyInfo;

/// <summary>
/// Gets a descriptor for the constructor, or <c>null</c> if this instance
/// does not represent a constructor.
/// </summary>
public ConstructorInfo? ConstructorInfo { get; }

/// <inheritdoc />
public bool Equals(ModelMetadataIdentity other)
{
Expand All @@ -191,7 +225,8 @@ public bool Equals(ModelMetadataIdentity other)
ModelType == other.ModelType &&
Name == other.Name &&
ParameterInfo == other.ParameterInfo &&
PropertyInfo == other.PropertyInfo;
PropertyInfo == other.PropertyInfo &&
ConstructorInfo == other.ConstructorInfo;
}

/// <inheritdoc />
Expand All @@ -210,6 +245,7 @@ public override int GetHashCode()
hash.Add(Name, StringComparer.Ordinal);
hash.Add(ParameterInfo);
hash.Add(PropertyInfo);
hash.Add(ConstructorInfo);
return hash.ToHashCode();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,10 @@ public enum ModelMetadataKind
/// Used for <see cref="ModelMetadata"/> for a parameter.
/// </summary>
Parameter,

/// <summary>
/// <see cref="ModelMetadata"/> for a constructor.
/// </summary>
Constructor,
}
}
}
Loading