Skip to content

Commit b843cc3

Browse files
committed
Merge remote-tracking branch 'upstream/main' into BlazorHotReloadPackageV2
2 parents 26ecd04 + 5f21e7c commit b843cc3

File tree

31 files changed

+1350
-174
lines changed

31 files changed

+1350
-174
lines changed

eng/Version.Details.xml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -396,17 +396,17 @@
396396
<Uri>https://github.com/dotnet/dotnet</Uri>
397397
<Sha>23101ed07a38169d3e59d63b9d4d33e6d1d609bb</Sha>
398398
</Dependency>
399-
<Dependency Name="Microsoft.Extensions.Caching.Hybrid" Version="9.8.0-preview.1.25358.1">
399+
<Dependency Name="Microsoft.Extensions.Caching.Hybrid" Version="9.8.0-preview.1.25361.1">
400400
<Uri>https://github.com/dotnet/extensions</Uri>
401-
<Sha>23c62b80989f7baf55dc394829895b636f960fdc</Sha>
401+
<Sha>cc0d010d068ddab0c5951b6cfc5793d379c0532c</Sha>
402402
</Dependency>
403-
<Dependency Name="Microsoft.Extensions.Diagnostics.Testing" Version="9.8.0-preview.1.25358.1">
403+
<Dependency Name="Microsoft.Extensions.Diagnostics.Testing" Version="9.8.0-preview.1.25361.1">
404404
<Uri>https://github.com/dotnet/extensions</Uri>
405-
<Sha>23c62b80989f7baf55dc394829895b636f960fdc</Sha>
405+
<Sha>cc0d010d068ddab0c5951b6cfc5793d379c0532c</Sha>
406406
</Dependency>
407-
<Dependency Name="Microsoft.Extensions.TimeProvider.Testing" Version="9.8.0-preview.1.25358.1">
407+
<Dependency Name="Microsoft.Extensions.TimeProvider.Testing" Version="9.8.0-preview.1.25361.1">
408408
<Uri>https://github.com/dotnet/extensions</Uri>
409-
<Sha>23c62b80989f7baf55dc394829895b636f960fdc</Sha>
409+
<Sha>cc0d010d068ddab0c5951b6cfc5793d379c0532c</Sha>
410410
</Dependency>
411411
<Dependency Name="NuGet.Frameworks" Version="6.2.4">
412412
<Uri>https://github.com/nuget/nuget.client</Uri>

eng/Versions.props

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -143,9 +143,9 @@
143143
<SystemNumericsTensorsVersion>10.0.0-preview.7.25358.102</SystemNumericsTensorsVersion>
144144
<SystemRuntimeCachingVersion>10.0.0-preview.7.25358.102</SystemRuntimeCachingVersion>
145145
<!-- Packages from dotnet/extensions -->
146-
<MicrosoftExtensionsCachingHybridVersion>9.8.0-preview.1.25358.1</MicrosoftExtensionsCachingHybridVersion>
147-
<MicrosoftExtensionsDiagnosticsTestingVersion>9.8.0-preview.1.25358.1</MicrosoftExtensionsDiagnosticsTestingVersion>
148-
<MicrosoftExtensionsTimeProviderTestingVersion>9.8.0-preview.1.25358.1</MicrosoftExtensionsTimeProviderTestingVersion>
146+
<MicrosoftExtensionsCachingHybridVersion>9.8.0-preview.1.25361.1</MicrosoftExtensionsCachingHybridVersion>
147+
<MicrosoftExtensionsDiagnosticsTestingVersion>9.8.0-preview.1.25361.1</MicrosoftExtensionsDiagnosticsTestingVersion>
148+
<MicrosoftExtensionsTimeProviderTestingVersion>9.8.0-preview.1.25361.1</MicrosoftExtensionsTimeProviderTestingVersion>
149149
<!-- Packages from dotnet/efcore -->
150150
<dotnetefVersion>10.0.0-preview.7.25358.102</dotnetefVersion>
151151
<MicrosoftEntityFrameworkCoreInMemoryVersion>10.0.0-preview.7.25358.102</MicrosoftEntityFrameworkCoreInMemoryVersion>
@@ -325,8 +325,8 @@
325325
<XunitExtensibilityCoreVersion>$(XunitVersion)</XunitExtensibilityCoreVersion>
326326
<XunitExtensibilityExecutionVersion>$(XunitVersion)</XunitExtensibilityExecutionVersion>
327327
<MicrosoftDataSqlClientVersion>5.2.2</MicrosoftDataSqlClientVersion>
328-
<MicrosoftOpenApiVersion>2.0.0-preview.29</MicrosoftOpenApiVersion>
329-
<MicrosoftOpenApiYamlReaderVersion>2.0.0-preview.29</MicrosoftOpenApiYamlReaderVersion>
328+
<MicrosoftOpenApiVersion>2.0.0</MicrosoftOpenApiVersion>
329+
<MicrosoftOpenApiYamlReaderVersion>2.0.0</MicrosoftOpenApiYamlReaderVersion>
330330
<!-- dotnet tool versions (see also auto-updated DotnetEfVersion property). -->
331331
<DotnetDumpVersion>6.0.322601</DotnetDumpVersion>
332332
<DotnetServeVersion>1.10.93</DotnetServeVersion>

src/Components/Components/src/PublicAPI.Unshipped.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#nullable enable
22
*REMOVED*Microsoft.AspNetCore.Components.ResourceAsset.ResourceAsset(string! url, System.Collections.Generic.IReadOnlyList<Microsoft.AspNetCore.Components.ResourceAssetProperty!>? properties) -> void
33
Microsoft.AspNetCore.Components.ResourceAsset.ResourceAsset(string! url, System.Collections.Generic.IReadOnlyList<Microsoft.AspNetCore.Components.ResourceAssetProperty!>? properties = null) -> void
4-
Microsoft.AspNetCore.Components.Routing.Router.NotFoundPage.get -> System.Type!
4+
Microsoft.AspNetCore.Components.Routing.Router.NotFoundPage.get -> System.Type?
55
Microsoft.AspNetCore.Components.Routing.Router.NotFoundPage.set -> void
66
Microsoft.AspNetCore.Components.Infrastructure.ComponentsMetricsServiceCollectionExtensions
77
Microsoft.AspNetCore.Components.NavigationManager.OnNotFound -> System.EventHandler<Microsoft.AspNetCore.Components.Routing.NotFoundEventArgs!>!

src/Components/Components/src/Routing/Router.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,14 +70,15 @@ static readonly IReadOnlyDictionary<string, object> _emptyParametersDictionary
7070
/// Gets or sets the content to display when no match is found for the requested route.
7171
/// </summary>
7272
[Parameter]
73+
[Obsolete("NotFound is deprecated. Use NotFoundPage instead.")]
7374
public RenderFragment NotFound { get; set; }
7475

7576
/// <summary>
7677
/// Gets or sets the page content to display when no match is found for the requested route.
7778
/// </summary>
7879
[Parameter]
7980
[DynamicallyAccessedMembers(LinkerFlags.Component)]
80-
public Type NotFoundPage { get; set; } = default!;
81+
public Type? NotFoundPage { get; set; }
8182

8283
/// <summary>
8384
/// Gets or sets the content to display when a match is found for the requested route.
@@ -143,6 +144,12 @@ public async Task SetParametersAsync(ParameterView parameters)
143144

144145
if (NotFoundPage != null)
145146
{
147+
#pragma warning disable CS0618 // Type or member is obsolete
148+
if (NotFound != null)
149+
{
150+
throw new InvalidOperationException($"Setting {nameof(NotFound)} and {nameof(NotFoundPage)} properties simultaneously is not supported. Use either {nameof(NotFound)} or {nameof(NotFoundPage)}.");
151+
}
152+
#pragma warning restore CS0618 // Type or member is obsolete
146153
if (!typeof(IComponent).IsAssignableFrom(NotFoundPage))
147154
{
148155
throw new InvalidOperationException($"The type {NotFoundPage.FullName} " +
@@ -401,10 +408,12 @@ private void RenderNotFound()
401408
new RouteData(NotFoundPage, _emptyParametersDictionary));
402409
builder.CloseComponent();
403410
}
411+
#pragma warning disable CS0618 // Type or member is obsolete
404412
else if (NotFound != null)
405413
{
406414
NotFound(builder);
407415
}
416+
#pragma warning restore CS0618 // Type or member is obsolete
408417
else
409418
{
410419
DefaultNotFoundContent(builder);
@@ -429,6 +438,7 @@ async Task IHandleAfterRender.OnAfterRenderAsync()
429438

430439
private static partial class Log
431440
{
441+
#pragma warning disable CS0618 // Type or member is obsolete
432442
[LoggerMessage(1, LogLevel.Debug, $"Displaying {nameof(NotFound)} because path '{{Path}}' with base URI '{{BaseUri}}' does not match any component route", EventName = "DisplayingNotFound")]
433443
internal static partial void DisplayingNotFound(ILogger logger, string path, string baseUri);
434444

@@ -440,5 +450,6 @@ private static partial class Log
440450

441451
[LoggerMessage(4, LogLevel.Debug, $"Displaying {nameof(NotFound)} on request", EventName = "DisplayingNotFoundOnRequest")]
442452
internal static partial void DisplayingNotFound(ILogger logger);
453+
#pragma warning restore CS0618 // Type or member is obsolete
443454
}
444455
}

src/Components/Components/test/Routing/RouterTest.cs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
33

4+
#pragma warning disable CS0618 // Type or member is obsolete
5+
46
using System.Reflection;
57
using Microsoft.AspNetCore.Components.RenderTree;
68
using Microsoft.AspNetCore.Components.Test.Helpers;
@@ -265,6 +267,40 @@ await _renderer.Dispatcher.InvokeAsync(() =>
265267
Assert.Equal("Not found", renderedFrame.TextContent);
266268
}
267269

270+
[Fact]
271+
public async Task ThrowsExceptionWhenBothNotFoundAndNotFoundPageAreSet()
272+
{
273+
// Arrange
274+
var services = new ServiceCollection();
275+
services.AddSingleton<ILoggerFactory>(NullLoggerFactory.Instance);
276+
services.AddSingleton<NavigationManager>(_navigationManager);
277+
services.AddSingleton<INavigationInterception, TestNavigationInterception>();
278+
services.AddSingleton<IScrollToLocationHash, TestScrollToLocationHash>();
279+
var serviceProvider = services.BuildServiceProvider();
280+
281+
var renderer = new TestRenderer(serviceProvider);
282+
renderer.ShouldHandleExceptions = true;
283+
var router = (Router)renderer.InstantiateComponent<Router>();
284+
router.AppAssembly = Assembly.GetExecutingAssembly();
285+
router.Found = routeData => (builder) => builder.AddContent(0, $"Rendering route matching {routeData.PageType}");
286+
renderer.AssignRootComponentId(router);
287+
288+
var parameters = new Dictionary<string, object>
289+
{
290+
{ nameof(Router.AppAssembly), typeof(RouterTest).Assembly },
291+
{ nameof(Router.NotFound), (RenderFragment)(builder => builder.AddContent(0, "Custom not found")) },
292+
{ nameof(Router.NotFoundPage), typeof(NotFoundTestComponent) }
293+
};
294+
295+
// Act & Assert
296+
var exception = await Assert.ThrowsAsync<InvalidOperationException>(async () =>
297+
await renderer.Dispatcher.InvokeAsync(() =>
298+
router.SetParametersAsync(ParameterView.FromDictionary(parameters))));
299+
300+
Assert.Contains("Setting NotFound and NotFoundPage properties simultaneously is not supported", exception.Message);
301+
Assert.Contains("Use either NotFound or NotFoundPage", exception.Message);
302+
}
303+
268304
internal class TestNavigationManager : NavigationManager
269305
{
270306
public TestNavigationManager() =>
@@ -306,4 +342,8 @@ public class MatchAnythingComponent : ComponentBase { }
306342

307343
[Route("a/b/c")]
308344
public class MultiSegmentRouteComponent : ComponentBase { }
345+
346+
[Route("not-found")]
347+
public class NotFoundTestComponent : ComponentBase { }
348+
309349
}

src/Components/WebAssembly/JSInterop/src/WebAssemblyJSObjectReferenceJsonConverter.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,12 @@ public override bool CanConvert(Type typeToConvert)
2626
public override IJSObjectReference? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
2727
{
2828
var id = JSObjectReferenceJsonWorker.ReadJSObjectReferenceIdentifier(ref reader);
29+
30+
if (id == -1)
31+
{
32+
return null;
33+
}
34+
2935
return new WebAssemblyJSObjectReference(_jsRuntime, id);
3036
}
3137

src/Components/WebAssembly/WebAssembly/test/JSObjectReferenceJsonConverterTest.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,17 @@ public void Read_ReadsJson_IJSInProcessObjectReference()
4444
// Assert
4545
Assert.Equal(expectedId, deserialized?.Id);
4646
}
47+
48+
[Fact]
49+
public void Read_ReturnsNull_WhenIdIsMinusOne()
50+
{
51+
// Arrange
52+
var json = "{\"__jsObjectId\":-1}";
53+
54+
// Act
55+
var deserialized = JsonSerializer.Deserialize<IJSObjectReference>(json, JsonSerializerOptions);
56+
57+
// Assert
58+
Assert.Null(deserialized);
59+
}
4760
}

src/Components/test/E2ETest/Tests/InteropTest.cs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,6 @@ public void CanInvokeInteropMethods()
8989
["invokeVoidAsyncReturnsWithoutSerializing"] = "Success",
9090
["invokeVoidAsyncReturnsWithoutSerializingInJSObjectReference"] = "Success",
9191
["invokeAsyncThrowsSerializingCircularStructure"] = "Success",
92-
["invokeAsyncThrowsUndefinedJSObjectReference"] = "Success",
93-
["invokeAsyncThrowsNullJSObjectReference"] = "Success",
9492
["disposeJSObjectReferenceAsync"] = "Success",
9593
// GetValue tests
9694
["getValueFromDataPropertyAsync"] = "10",
@@ -108,7 +106,12 @@ public void CanInvokeInteropMethods()
108106
["invokeConstructorWithClassConstructorAsync.function"] = "6",
109107
["invokeConstructorWithNonConstructorAsync"] = "Success",
110108
// Function reference tests
111-
["changeFunctionViaObjectReferenceAsync"] = "42"
109+
["changeFunctionViaObjectReferenceAsync"] = "42",
110+
// JS Object Nullable reference tests
111+
["invokeAsyncUndefinedJSObjectReference"] = "Success",
112+
["invokeAsyncNullJSObjectReference"] = "Success",
113+
["invokeAsyncNullFromVariableJSObjectReference"] = "Success",
114+
["invokeAsyncNonExistentJSObjectReference"] = "Success",
112115
};
113116

114117
var expectedSyncValues = new Dictionary<string, string>
@@ -148,8 +151,6 @@ public void CanInvokeInteropMethods()
148151
["invokeVoidReturnsWithoutSerializingIJSInProcessRuntime"] = "Success",
149152
["invokeVoidReturnsWithoutSerializingInIJSInProcessObjectReference"] = "Success",
150153
["invokeThrowsSerializingCircularStructure"] = "Success",
151-
["invokeThrowsUndefinedJSObjectReference"] = "Success",
152-
["invokeThrowsNullJSObjectReference"] = "Success",
153154
["stringValueUpperSync"] = "MY STRING",
154155
["testDtoNonSerializedValueSync"] = "99999",
155156
["testDtoSync"] = "Same",
@@ -174,7 +175,12 @@ public void CanInvokeInteropMethods()
174175
["invokeConstructorWithClassConstructor.function"] = "6",
175176
["invokeConstructorWithNonConstructor"] = "Success",
176177
// Function reference tests
177-
["changeFunctionViaObjectReference"] = "42"
178+
["changeFunctionViaObjectReference"] = "42",
179+
// JS Object Nullable reference tests
180+
["invokeUndefinedJSObjectReference"] = "Success",
181+
["invokeNullJSObjectReference"] = "Success",
182+
["invokeNullFromVariableJSObjectReference"] = "Success",
183+
["invokeNonExistentJSObjectReference"] = "Success",
178184
};
179185

180186
// Include the sync assertions only when running under WebAssembly

0 commit comments

Comments
 (0)