Skip to content

Commit

Permalink
Merge pull request #50596 from dotnet-maestro-bot/merge/release/8.0-t…
Browse files Browse the repository at this point in the history
…o-main

[automated] Merge branch 'release/8.0' => 'main'
  • Loading branch information
BrennanConroy authored Sep 8, 2023
2 parents ddabebf + c3070ff commit 410efd4
Show file tree
Hide file tree
Showing 48 changed files with 1,379 additions and 532 deletions.
284 changes: 142 additions & 142 deletions eng/Version.Details.xml

Large diffs are not rendered by default.

142 changes: 71 additions & 71 deletions eng/Versions.props

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
<ItemGroup>
<Compile Include="$(ComponentsSharedSourceRoot)src\ArrayBuilder.cs" LinkBase="RenderTree" />
<Compile Include="$(ComponentsSharedSourceRoot)src\JsonSerializerOptionsProvider.cs" />
<Compile Include="$(ComponentsSharedSourceRoot)src\HotReloadManager.cs" LinkBase="HotReload" />
<Compile Include="$(SharedSourceRoot)LinkerFlags.cs" LinkBase="Shared" />
<Compile Include="$(SharedSourceRoot)QueryStringEnumerable.cs" LinkBase="Shared" />
</ItemGroup>
Expand Down
1 change: 1 addition & 0 deletions src/Components/Components/src/Routing/Router.cs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ static readonly IReadOnlyDictionary<string, object> _emptyParametersDictionary
/// over wildcards.
/// <para>This property is obsolete and configuring it does nothing.</para>
/// </summary>
[Obsolete("This property is obsolete and configuring it has not effect.")]
[Parameter] public bool PreferExactMatches { get; set; }

private RouteTable Routes { get; set; }
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using Microsoft.AspNetCore.Components.Endpoints;
using Microsoft.AspNetCore.Components.Endpoints.FormMapping;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;

namespace Microsoft.Extensions.DependencyInjection;

internal class DefaultRazorComponentsServiceOptionsConfiguration(IConfiguration configuration, ILoggerFactory loggerFactory)
: IPostConfigureOptions<RazorComponentsServiceOptions>
{
public IConfiguration Configuration { get; } = configuration;

public void PostConfigure(string? name, RazorComponentsServiceOptions options)
{
var value = Configuration[WebHostDefaults.DetailedErrorsKey];
options.DetailedErrors = string.Equals(value, "true", StringComparison.OrdinalIgnoreCase) ||
string.Equals(value, "1", StringComparison.OrdinalIgnoreCase);

options._formMappingOptions = new FormDataMapperOptions(loggerFactory)
{
MaxRecursionDepth = options.MaxFormMappingRecursionDepth,
MaxErrorCount = options.MaxFormMappingErrorCount,
MaxCollectionSize = options.MaxFormMappingCollectionSize,
MaxKeyBufferSize = options.MaxFormMappingKeySize
};
}
}

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,15 @@ public static class RazorComponentsServiceCollectionExtensions
/// Registers services required for server-side rendering of Razor Components.
/// </summary>
/// <param name="services">The service collection.</param>
/// <param name="configure">An <see cref="Action{RazorComponentOptions}"/> to configure the provided <see cref="RazorComponentsOptions"/>.</param>
/// <param name="configure">An <see cref="Action{RazorComponentOptions}"/> to configure the provided <see cref="RazorComponentsServiceOptions"/>.</param>
/// <returns>An <see cref="IRazorComponentsBuilder"/> that can be used to further configure the Razor component services.</returns>
[RequiresUnreferencedCode("Razor Components does not currently support trimming or native AOT.", Url = "https://aka.ms/aspnet/nativeaot")]
public static IRazorComponentsBuilder AddRazorComponents(this IServiceCollection services, Action<RazorComponentsOptions>? configure = null)
public static IRazorComponentsBuilder AddRazorComponents(this IServiceCollection services, Action<RazorComponentsServiceOptions>? configure = null)
{
ArgumentNullException.ThrowIfNull(services);

// Dependencies
services.AddLogging();
services.AddAntiforgery();

services.TryAddSingleton<RazorComponentsMarkerService>();
Expand All @@ -61,7 +62,8 @@ public static IRazorComponentsBuilder AddRazorComponents(this IServiceCollection
services.TryAddScoped<ComponentStatePersistenceManager>();
services.TryAddScoped<PersistentComponentState>(sp => sp.GetRequiredService<ComponentStatePersistenceManager>().State);
services.TryAddScoped<IErrorBoundaryLogger, PrerenderingErrorBoundaryLogger>();
services.TryAddEnumerable(ServiceDescriptor.Singleton<IConfigureOptions<RazorComponentsEndpointOptions>, RazorComponentsEndpointsDetailedErrorsConfiguration>());
services.TryAddEnumerable(
ServiceDescriptor.Singleton<IPostConfigureOptions<RazorComponentsServiceOptions>, DefaultRazorComponentsServiceOptionsConfiguration>());
services.TryAddScoped<EndpointRoutingStateProvider>();
services.TryAddScoped<IRoutingStateProvider>(sp => sp.GetRequiredService<EndpointRoutingStateProvider>());
services.AddSupplyValueFromQueryProvider();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,14 @@ namespace Microsoft.AspNetCore.Components.Endpoints;
/// <summary>
/// Provides options for configuring server-side rendering of Razor Components.
/// </summary>
public sealed class RazorComponentsOptions
public sealed class RazorComponentsServiceOptions
{
internal readonly FormDataMapperOptions _formMappingOptions = new();
internal FormDataMapperOptions _formMappingOptions = new();

/// <summary>
/// Gets or sets a value that determines whether to include detailed information on errors.
/// </summary>
public bool DetailedErrors { get; set; }

/// <summary>
/// Gets or sets the maximum number of elements allowed in a form collection.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ internal override bool TryRead(
out bool found)
{
TElement currentElement;
TBuffer buffer;
TBuffer? buffer = default;
bool foundCurrentElement;
bool currentElementSuccess;
bool succeded;
Expand All @@ -73,10 +73,10 @@ internal override bool TryRead(
{
context.PopPrefix("[0]");
}

if (!found)
{
result = default;
return succeded;
return TryReadSingleValueCollection(ref context, out result, ref found, ref buffer, ref succeded);
}

// We already know we found an element;
Expand All @@ -92,6 +92,15 @@ internal override bool TryRead(
currentElementSuccess = _elementConverter.TryRead(ref context, _elementType, options, out currentElement!, out foundCurrentElement);
succeded = succeded && currentElementSuccess;
}
catch
{
if (buffer != null)
{
// Ensure the buffer is cleaned up if we fail.
result = TCollectionPolicy.ToResult(buffer);
}
throw;
}
finally
{
context.PopPrefix("[1]");
Expand Down Expand Up @@ -120,6 +129,15 @@ internal override bool TryRead(
currentElementSuccess = _elementConverter.TryRead(ref context, _elementType, options, out currentElement!, out foundCurrentElement);
succeded = succeded && currentElementSuccess;
}
catch
{
if (buffer != null)
{
// Ensure the buffer is cleaned up if we fail.
result = TCollectionPolicy.ToResult(buffer);
}
throw;
}
finally
{
context.PopPrefix(prefix);
Expand Down Expand Up @@ -163,6 +181,15 @@ internal override bool TryRead(
currentElementSuccess = _elementConverter.TryRead(ref context, _elementType, options, out currentElement!, out foundCurrentElement);
succeded = succeded && currentElementSuccess;
}
catch
{
if (buffer != null)
{
// Ensure the buffer is cleaned up if we fail.
result = TCollectionPolicy.ToResult(buffer);
}
throw;
}
finally
{
context.PopPrefix(computedPrefix[..(charsWritten + 2)]);
Expand All @@ -189,4 +216,44 @@ internal override bool TryRead(
return succeded;
}
}

private bool TryReadSingleValueCollection(ref FormDataReader context, out TCollection? result, ref bool found, ref TBuffer? buffer, ref bool succeded)
{
if (_elementConverter is ISingleValueConverter<TElement> singleValueConverter &&
singleValueConverter.CanConvertSingleValue() &&
context.TryGetValues(out var values))
{
found = true;
buffer = TCollectionPolicy.CreateBuffer();

for (var i = 0; i < values.Count; i++)
{
var value = values[i];
try
{
if (!singleValueConverter.TryConvertValue(ref context, value!, out var elementValue))
{
succeded = false;
}
else
{
buffer = TCollectionPolicy.Add(ref buffer, elementValue);
}
}
catch (Exception ex)
{
succeded = false;
context.AddMappingError(ex, value);
}
};

result = TCollectionPolicy.ToResult(buffer);
}
else
{
result = default;
}

return succeded;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,12 @@

namespace Microsoft.AspNetCore.Components.Endpoints.FormMapping;

internal class EnumConverter<TEnum> : FormDataConverter<TEnum> where TEnum : struct, Enum
internal class EnumConverter<TEnum> : FormDataConverter<TEnum>, ISingleValueConverter<TEnum> where TEnum : struct, Enum
{
[RequiresDynamicCode(FormMappingHelpers.RequiresDynamicCodeMessage)]
[RequiresUnreferencedCode(FormMappingHelpers.RequiresUnreferencedCodeMessage)]
internal override bool TryRead(ref FormDataReader reader, Type type, FormDataMapperOptions options, out TEnum result, out bool found)
public bool CanConvertSingleValue() => true;

public bool TryConvertValue(ref FormDataReader reader, string value, out TEnum result)
{
found = reader.TryGetValue(out var value);
if (!found)
{
result = default;
return true;
}
if (Enum.TryParse(value, ignoreCase: true, out result))
{
return true;
Expand All @@ -30,4 +24,18 @@ internal override bool TryRead(ref FormDataReader reader, Type type, FormDataMap
return false;
}
}

[RequiresDynamicCode(FormMappingHelpers.RequiresDynamicCodeMessage)]
[RequiresUnreferencedCode(FormMappingHelpers.RequiresUnreferencedCodeMessage)]
internal override bool TryRead(ref FormDataReader reader, Type type, FormDataMapperOptions options, out TEnum result, out bool found)
{
found = reader.TryGetValue(out var value);
if (!found)
{
result = default;
return true;
}

return TryConvertValue(ref reader, value!, out result);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,27 @@

namespace Microsoft.AspNetCore.Components.Endpoints.FormMapping;

internal sealed class NullableConverter<T> : FormDataConverter<T?> where T : struct
internal sealed class NullableConverter<T>(FormDataConverter<T> nonNullableConverter) : FormDataConverter<T?>, ISingleValueConverter<T?> where T : struct
{
private readonly FormDataConverter<T> _nonNullableConverter;
private readonly FormDataConverter<T> _nonNullableConverter = nonNullableConverter;

public NullableConverter(FormDataConverter<T> nonNullableConverter)
public bool CanConvertSingleValue() => _nonNullableConverter is ISingleValueConverter<T> singleValueConverter &&
singleValueConverter.CanConvertSingleValue();

public bool TryConvertValue(ref FormDataReader reader, string value, out T? result)
{
_nonNullableConverter = nonNullableConverter;
var converter = (ISingleValueConverter<T>)_nonNullableConverter;

if (converter.TryConvertValue(ref reader, value, out var converted))
{
result = converted;
return true;
}
else
{
result = null;
return false;
}
}

[RequiresDynamicCode(FormMappingHelpers.RequiresDynamicCodeMessage)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,25 @@

namespace Microsoft.AspNetCore.Components.Endpoints.FormMapping;

internal sealed class ParsableConverter<T> : FormDataConverter<T>, ISingleValueConverter where T : IParsable<T>
internal sealed class ParsableConverter<T> : FormDataConverter<T>, ISingleValueConverter<T> where T : IParsable<T>
{
public bool CanConvertSingleValue() => true;

public bool TryConvertValue(ref FormDataReader reader, string value, out T result)
{
if (T.TryParse(value, reader.Culture, out result!))
{
return true;
}
else
{
var segment = reader.GetLastPrefixSegment();
reader.AddMappingError(FormattableStringFactory.Create(FormDataResources.ParsableMappingError, value, segment), value);
result = default!;
return false;
}
}

[RequiresDynamicCode(FormMappingHelpers.RequiresDynamicCodeMessage)]
[RequiresUnreferencedCode(FormMappingHelpers.RequiresUnreferencedCodeMessage)]
internal override bool TryRead(ref FormDataReader reader, Type type, FormDataMapperOptions options, out T? result, out bool found)
Expand All @@ -18,17 +35,9 @@ internal override bool TryRead(ref FormDataReader reader, Type type, FormDataMap
result = default;
return true;
}

if (T.TryParse(value, reader.Culture, out result))
{
return true;
}
else
{
var segment = reader.GetLastPrefixSegment();
reader.AddMappingError(FormattableStringFactory.Create(FormDataResources.ParsableMappingError, value, segment), value);
result = default;
return false;
return TryConvertValue(ref reader, value!, out result!);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ internal override CompiledComplexTypeConverter<T> CreateConverter(Type type, For
[RequiresUnreferencedCode(FormMappingHelpers.RequiresUnreferencedCodeMessage)]
private CompiledComplexTypeConverter<T>.ConverterDelegate CreateConverterBody(Type type, FormDataMapperOptions options)
{
var metadata = factory.GetOrCreateMetadataFor(type, options);
var metadata = factory.GetOrCreateMetadataFor(type, options) ??
throw new InvalidOperationException($"Could not resolve metadata for type '{type.FullName}'.");

var properties = metadata.Properties;
var constructorParameters = metadata.ConstructorParameters;

Expand Down
Loading

0 comments on commit 410efd4

Please sign in to comment.