Skip to content

[Validation] C# unions in component parameters and prerendered state #68480

Description

@oroztocil

Scenario contact: @oroztocil

Scenario

An app passes C# union values into components as parameters and keeps union data in persisted component state. This validates that union values survive the transition from prerendered HTML to a live interactive component, including a union whose active case is null, and that cases which look alike in JSON behave predictably.

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 the project needs <LangVersion>preview</LangVersion>.

What to build

A Blazor Web App with a small set of union types: an unambiguous pair such as (int, string), a nullable pair such as (int?, string), and a pair of records whose JSON shapes are hard to tell apart. Add a page that hands each union to a child component as a parameter and renders the active case. Prerender the page and let it become interactive. Also keep one union value in persisted component state so the client restores it instead of recomputing it.

Things to try

  • A union whose active case is null.
  • The two-record union with and without a [JsonUnion] classifier.
  • A union nested inside a larger object that is itself passed as a parameter.
  • Changing the active case after interactivity starts.
  • In Interactive Auto, a first visit with browser storage cleared and then a reload once assets are cached.
  • A union in a binding source the docs call unsupported, such as a form field, query string or route value.

Expected behavior

A union value comes out of prerendering as the same case it went in as, and the ways it can fail are visible rather than silent.

Must hold

  • The active case rendered before interactivity starts is the same case, with the same value, as the one rendered after.
  • A union whose active case is null comes back as null rather than throwing or resolving to a different case.
  • With a classifier applied, each record case round-trips as the case it started as.
  • Without a classifier, the ambiguous union either resolves correctly or fails with a message naming the ambiguity, rather than silently producing the wrong case.
  • A union used in an unsupported binding source fails in a way that names the limitation, rather than binding to a default value.

Expected differences between configurations

  • Interactive Server and Interactive WebAssembly deserialize parameters through different code paths, so a case that survives in one and not the other is a finding rather than a configuration difference.
  • Interactive Auto exercises both of those paths across the two visits, so run it against a cleared browser cache as well as a warm one.

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