Skip to content

Commit 273fcf1

Browse files
committed
Merge branch 'main' into blazor_dedup_OnConnectionDownAsync
2 parents 89b709a + 3e86bc0 commit 273fcf1

File tree

25 files changed

+1259
-146
lines changed

25 files changed

+1259
-146
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/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

src/Components/test/testassets/BasicTestApp/InteropComponent.razor

Lines changed: 125 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -167,33 +167,6 @@
167167
ReturnValues["invokeAsyncThrowsSerializingCircularStructure"] = $"Failure: {ex.Message}";
168168
}
169169

170-
try
171-
{
172-
var undefinedJsObjectReference = await JSRuntime.InvokeAsync<IJSObjectReference>("returnUndefined");
173-
ReturnValues["invokeAsyncThrowsUndefinedJSObjectReference"] = undefinedJsObjectReference is null ? "Failure: null" : "Failure: not null";
174-
}
175-
catch (JSException)
176-
{
177-
ReturnValues["invokeAsyncThrowsUndefinedJSObjectReference"] = "Success";
178-
}
179-
catch (Exception ex)
180-
{
181-
ReturnValues["invokeAsyncThrowsUndefinedJSObjectReference"] = $"Failure: {ex.Message}";
182-
}
183-
184-
try
185-
{
186-
var nullJsObjectReference = await JSRuntime.InvokeAsync<IJSObjectReference>("returnNull");
187-
ReturnValues["invokeAsyncThrowsNullJSObjectReference"] = nullJsObjectReference is null ? "Failure: null" : "Failure: not null";
188-
}
189-
catch (JSException)
190-
{
191-
ReturnValues["invokeAsyncThrowsNullJSObjectReference"] = "Success";
192-
}
193-
catch (Exception ex)
194-
{
195-
ReturnValues["invokeAsyncThrowsNullJSObjectReference"] = $"Failure: {ex.Message}";
196-
}
197170

198171
var jsObjectReference = await JSRuntime.InvokeAsync<IJSObjectReference>("returnJSObjectReference");
199172
ReturnValues["jsObjectReference.identity"] = await jsObjectReference.InvokeAsync<string>("identity", "Invoked from JSObjectReference");
@@ -308,6 +281,13 @@
308281
FunctionReferenceTests();
309282
}
310283

284+
await JSObjectReferenceAsyncTests();
285+
286+
if (shouldSupportSyncInterop)
287+
{
288+
JSObjectReferenceTests();
289+
}
290+
311291
Invocations = invocations;
312292
DoneWithInterop = true;
313293
}
@@ -394,34 +374,6 @@
394374
ReturnValues["invokeThrowsSerializingCircularStructure"] = $"Failure: {ex.Message}";
395375
}
396376

397-
try
398-
{
399-
var undefinedJsObjectReference = inProcRuntime.Invoke<IJSObjectReference>("returnUndefined");
400-
ReturnValues["invokeThrowsUndefinedJSObjectReference"] = undefinedJsObjectReference is null ? "Failure: null" : "Failure: not null";
401-
}
402-
catch (JSException)
403-
{
404-
ReturnValues["invokeThrowsUndefinedJSObjectReference"] = "Success";
405-
}
406-
catch (Exception ex)
407-
{
408-
ReturnValues["invokeThrowsUndefinedJSObjectReference"] = $"Failure: {ex.Message}";
409-
}
410-
411-
try
412-
{
413-
var nullJsObjectReference = inProcRuntime.Invoke<IJSObjectReference>("returnNull");
414-
ReturnValues["invokeThrowsNullJSObjectReference"] = nullJsObjectReference is null ? "Failure: null" : "Failure: not null";
415-
}
416-
catch (JSException)
417-
{
418-
ReturnValues["invokeThrowsNullJSObjectReference"] = "Success";
419-
}
420-
catch (Exception ex)
421-
{
422-
ReturnValues["invokeThrowsNullJSObjectReference"] = $"Failure: {ex.Message}";
423-
}
424-
425377
var jsInProcObjectReference = inProcRuntime.Invoke<IJSInProcessObjectReference>("returnJSObjectReference");
426378
ReturnValues["jsInProcessObjectReference.identity"] = jsInProcObjectReference.Invoke<string>("identity", "Invoked from JSInProcessObjectReference");
427379

@@ -626,6 +578,124 @@
626578
ReturnValues["changeFunctionViaObjectReference"] = testClassRef.Invoke<int>("getTextLength").ToString();
627579
}
628580

581+
private async Task JSObjectReferenceAsyncTests()
582+
{
583+
try
584+
{
585+
var undefinedJsObjectReference = await JSRuntime.InvokeAsync<IJSObjectReference>("jsInteropTests.returnUndefined");
586+
ReturnValues["invokeAsyncUndefinedJSObjectReference"] = undefinedJsObjectReference is null ? "Success" : $"Failure: not null (type: {undefinedJsObjectReference.GetType().FullName})";
587+
}
588+
catch (JSException ex)
589+
{
590+
ReturnValues["invokeAsyncUndefinedJSObjectReference"] = $"Failure: {ex.Message}";
591+
}
592+
catch (Exception ex)
593+
{
594+
ReturnValues["invokeAsyncUndefinedJSObjectReference"] = $"Failure: {ex.Message}";
595+
}
596+
597+
try
598+
{
599+
var nullJsObjectReference = await JSRuntime.InvokeAsync<IJSObjectReference>("jsInteropTests.returnNull");
600+
ReturnValues["invokeAsyncNullJSObjectReference"] = nullJsObjectReference is null ? "Success" : $"Failure: not null (type: {nullJsObjectReference.GetType().FullName})";
601+
}
602+
catch (JSException ex)
603+
{
604+
ReturnValues["invokeAsyncNullJSObjectReference"] = $"Failure: {ex.Message}";
605+
}
606+
catch (Exception ex)
607+
{
608+
ReturnValues["invokeAsyncNullJSObjectReference"] = $"Failure: {ex.Message}";
609+
}
610+
611+
try
612+
{
613+
var nullVariableJsObjectReference = await JSRuntime.GetValueAsync<IJSObjectReference>("jsInteropTests.testObject.nullProperty");
614+
ReturnValues["invokeAsyncNullFromVariableJSObjectReference"] = nullVariableJsObjectReference is null ? "Success" : $"Failure: not null (type: {nullVariableJsObjectReference.GetType().FullName})";
615+
}
616+
catch (JSException ex)
617+
{
618+
ReturnValues["invokeAsyncNullFromVariableJSObjectReference"] = $"Failure: {ex.Message}";
619+
}
620+
catch (Exception ex)
621+
{
622+
ReturnValues["invokeAsyncNullFromVariableJSObjectReference"] = $"Failure: {ex.Message}";
623+
}
624+
625+
try
626+
{
627+
await JSRuntime.GetValueAsync<IJSObjectReference>("nonexistend");
628+
}
629+
catch (JSException)
630+
{
631+
ReturnValues["invokeAsyncNonExistentJSObjectReference"] = "Success";
632+
}
633+
catch (Exception ex)
634+
{
635+
ReturnValues["invokeAsyncNonExistentJSObjectReference"] = $"Failure: {ex.Message}";
636+
}
637+
}
638+
639+
private void JSObjectReferenceTests()
640+
{
641+
var inProcRuntime = ((IJSInProcessRuntime)JSRuntime);
642+
643+
try
644+
{
645+
var undefinedJsObjectReference = inProcRuntime.Invoke<IJSObjectReference>("returnUndefined");
646+
ReturnValues["invokeUndefinedJSObjectReference"] = undefinedJsObjectReference is null ? "Success" : $"Failure: not null (type: {undefinedJsObjectReference.GetType().FullName})";
647+
}
648+
catch (JSException ex)
649+
{
650+
ReturnValues["invokeUndefinedJSObjectReference"] = $"Failure: {ex.Message}";
651+
}
652+
catch (Exception ex)
653+
{
654+
ReturnValues["invokeUndefinedJSObjectReference"] = $"Failure: {ex.Message}";
655+
}
656+
657+
try
658+
{
659+
var nullJsObjectReference = inProcRuntime.Invoke<IJSObjectReference>("returnNull");
660+
ReturnValues["invokeNullJSObjectReference"] = nullJsObjectReference is null ? "Success" : $"Failure: not null (type: {nullJsObjectReference.GetType().FullName})";
661+
}
662+
catch (JSException ex)
663+
{
664+
ReturnValues["invokeNullJSObjectReference"] = $"Failure: {ex.Message}";
665+
}
666+
catch (Exception ex)
667+
{
668+
ReturnValues["invokeNullJSObjectReference"] = $"Failure: {ex.Message}";
669+
}
670+
671+
try
672+
{
673+
var nullVariableJsObjectReference = inProcRuntime.GetValue<IJSObjectReference>("jsInteropTests.testObject.nullProperty");
674+
ReturnValues["invokeNullFromVariableJSObjectReference"] = nullVariableJsObjectReference is null ? "Success" : $"Failure: not null (type: {nullVariableJsObjectReference.GetType().FullName})";
675+
}
676+
catch (JSException ex)
677+
{
678+
ReturnValues["invokeNullFromVariableJSObjectReference"] = $"Failure: {ex.Message}";
679+
}
680+
catch (Exception ex)
681+
{
682+
ReturnValues["invokeNullFromVariableJSObjectReference"] = $"Failure: {ex.Message}";
683+
}
684+
685+
try
686+
{
687+
inProcRuntime.GetValue<IJSObjectReference>("nonexistend");
688+
}
689+
catch (JSException)
690+
{
691+
ReturnValues["invokeNonExistentJSObjectReference"] = "Success";
692+
}
693+
catch (Exception ex)
694+
{
695+
ReturnValues["invokeNonExistentJSObjectReference"] = $"Failure: {ex.Message}";
696+
}
697+
}
698+
629699
public class PassDotNetObjectByRefArgs
630700
{
631701
public string StringValue { get; set; }

src/Components/test/testassets/BasicTestApp/wwwroot/js/jsinteroptests.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,8 @@ const testObject = {
234234
},
235235
set setOnlyProperty(value) {
236236
this.num = value;
237-
}
237+
},
238+
nullProperty: null
238239
}
239240

240241
window.jsInteropTests = {

src/Framework/AspNetCoreAnalyzers/src/SourceGenerators/PublicTopLevelProgramGenerator.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,10 @@ public class PublicProgramSourceGenerator : IIncrementalGenerator
1212
{
1313
private const string PublicPartialProgramClassSource = """
1414
// <auto-generated />
15-
#pragma warning disable CS1591
15+
/// <summary>
16+
/// Auto-generated public partial Program class for top-level statement apps.
17+
/// </summary>
1618
public partial class Program { }
17-
#pragma warning restore CS1591
1819
""";
1920

2021
public void Initialize(IncrementalGeneratorInitializationContext context)

src/Framework/AspNetCoreAnalyzers/test/SourceGenerators/PublicTopLevelProgramGeneratorTests.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,10 @@ public class PublicTopLevelProgramGeneratorTests
99
{
1010
private const string ExpectedGeneratedSource = """
1111
// <auto-generated />
12-
#pragma warning disable CS1591
12+
/// <summary>
13+
/// Auto-generated public partial Program class for top-level statement apps.
14+
/// </summary>
1315
public partial class Program { }
14-
#pragma warning restore CS1591
1516
""";
1617

1718
[Fact]

src/JSInterop/Microsoft.JSInterop.JS/src/src/Microsoft.JSInterop.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,12 @@ export module DotNet {
155155
* @throws Error if the given value is not an Object.
156156
*/
157157
export function createJSObjectReference(jsObject: any): any {
158+
if (jsObject === null || jsObject === undefined) {
159+
return {
160+
[jsObjectIdKey]: -1
161+
};
162+
}
163+
158164
if (jsObject && (typeof jsObject === "object" || jsObject instanceof Function)) {
159165
cachedJSObjectsById[nextJsObjectId] = new JSObject(jsObject);
160166

@@ -220,7 +226,7 @@ export module DotNet {
220226
export function disposeJSObjectReference(jsObjectReference: any): void {
221227
const id = jsObjectReference && jsObjectReference[jsObjectIdKey];
222228

223-
if (typeof id === "number") {
229+
if (typeof id === "number" && id !== -1) {
224230
disposeJSObjectReferenceById(id);
225231
}
226232
}

0 commit comments

Comments
 (0)