Skip to content

[Validation] data-permanent preserves the marked element's own attributes #68527

Description

@oroztocil

Scenario contact: @javiercn

Scenario

This scenario validates that a reported bug is fixed. Enhanced navigation keeps the existing document and patches it, and data-permanent marks the parts that must survive untouched.

In .NET 10 the attribute only protected an element's descendants. Changes made to the marked element itself, such as a class added by script, were lost on the next enhanced navigation. Moving the attribute to a wrapper made it work, which is what made the behavior confusing to diagnose. (#51021)

.NET 11 uses data-permanent to decide whether to synchronise the element's own attributes as well as whether to recurse into it.

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)

The DOM merge runs the same way whatever render mode the pages use, and the reported bug reproduces with statically rendered pages.

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

What to build

Two statically rendered pages with links between them, and a layout rendered on both. In the layout put three elements:

<div id="keep" data-permanent data-count="1">original</div>
<div id="control" data-count="1">original</div>
<div data-permanent><div id="wrapped" data-count="1">original</div></div>

Add a script that runs after load and changes each element itself, not only its children:

for (const id of ['keep', 'control', 'wrapped']) {
  const el = document.getElementById(id);
  el.classList.add('expand');
  el.setAttribute('data-count', '2');
  el.textContent = 'mutated';
}

#keep is the case that was broken. #control is unmarked, so it should be reset. #wrapped is protected by a marked parent, which is the arrangement that already worked in .NET 10.

Things to try

  • Navigate to the other page and back, then inspect all three elements in developer tools. This is the reported repro.
  • Repeat the round trip several times without a full reload.
  • Repeat on .NET 10 to see the original failure.

Expected behavior

An element marked data-permanent survives a navigation exactly as it was, including changes made to the element itself.

Must hold

  • After navigating away and back, #keep still has the expand class, still has data-count="2", and still reads mutated.
  • #control is reset to its original markup, confirming the marking is what made the difference rather than the navigation being a no-op.
  • #wrapped keeps its changes too, so the arrangement that worked before still works.
  • Repeating the round trip several times produces no accumulating errors in the console.

Evidence to capture

The markup of #keep and #control from developer tools, before and after the navigation, so the two can be compared.

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

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions