Skip to content

[Validation] C# unions across JavaScript interop #68481

Description

@oroztocil

Scenario contact: @oroztocil

Scenario

An app exchanges C# union values with JavaScript in both directions: as arguments to JavaScript calls, as values returned from JavaScript, and as parameters and return values of methods JavaScript calls back into .NET. This validates that a union serializes as its active case, comes back as the right case, and fails understandably when the incoming JSON matches no case.

Minimum build

.NET 11 Preview 7 or later.

Configurations to cover

  • Blazor Web App
    • Static SSR
    • Interactive Server
    • Interactive WebAssembly
    • Interactive Auto
  • Standalone WebAssembly
  • Hybrid (MAUI)

Also exercise

  • Published output
  • An existing .NET 10 app upgraded to .NET 11
  • Trimming or ahead-of-time compilation
  • More than one server instance, or a proxy in front
  • Hot Reload
  • An IDE as well as the command line
  • Container

Setup

Union types are a preview language feature, so each project needs <LangVersion>preview</LangVersion>.

What to build

An app with a small JavaScript module and a page that exercises interop in both directions. Define an unambiguous union such as (int, string), a nullable union such as (int?, string), and a union of two records whose JSON shapes are hard to tell apart. Pass each of them to JavaScript, return each of them from JavaScript, and add a method JavaScript can invoke that both accepts and returns a union. Show the results in the page, and watch what actually crosses the boundary in the browser console.

Things to try

  • A union whose active case is null.
  • A union nested inside a larger object rather than passed on its own.
  • JavaScript returning a shape that matches no declared case, or that matches more than one.
  • The two-record union with and without a [JsonUnion] classifier.

Expected behavior

Only the active case crosses the boundary, it comes back as the same case, and anything JavaScript sends that does not fit is reported rather than guessed at.

Must hold

  • An integer case arrives in JavaScript as a number, a string case as a string, and a record case as that record's own object, with no wrapper object around the active case.
  • A value returned from JavaScript becomes the same case it was sent as, including when the active case is null.
  • A union passed to and returned from a method JavaScript invokes on .NET round-trips as the same case.
  • JSON matching no declared case produces an error naming the problem rather than a default value.
  • The ambiguous record union either resolves through its classifier or fails with a message naming the ambiguity.

Expected differences between configurations

No user-observable differences are expected between the covered configurations.

Evidence to capture

The actual JSON that crossed the boundary for each union case, taken from the browser console or the network log, rather than a description of it.

Documentation to use

What to report

Report results using the format described in the validation testing manual. Include link to a repository with the test app.

Metadata

Metadata

Labels

ValidationThis issue is used to track validation effortsarea-blazorIncludes: Blazor, Razor Componentsvalidation-scenarioThis issue describes a validation testing scenario

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions