Initialize PartialTagHelper.ViewData to support view-data-* prefix attributes#65577
Open
kubaflo wants to merge 1 commit intodotnet:mainfrom
Open
Initialize PartialTagHelper.ViewData to support view-data-* prefix attributes#65577kubaflo wants to merge 1 commit intodotnet:mainfrom
kubaflo wants to merge 1 commit intodotnet:mainfrom
Conversation
Contributor
|
Hey @dotnet/aspnet-build, looks like this PR is something you want to take a look at. |
Contributor
There was a problem hiding this comment.
Pull request overview
Fixes a NullReferenceException in PartialTagHelper when using view-data-* prefixed attributes without explicitly providing view-data, by ensuring ViewData is initialized from the current ViewContext early enough for prefix-attribute binding.
Changes:
- Initialize
PartialTagHelper.ViewDatafromViewContext.ViewDatain theViewContextsetter whenViewDatais stillnull. - Add MVC unit tests covering the regression and ensuring the auto-initialized
ViewDatadoesn’t mutate the parentViewContext.ViewData. - Add multiple new
.github/skills/*skill docs/scripts and associated bash tests.
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| src/Mvc/Mvc.TagHelpers/src/PartialTagHelper.cs | Auto-initializes ViewData when ViewContext is set to support view-data-* prefix attributes. |
| src/Mvc/Mvc.TagHelpers/test/PartialTagHelperTest.cs | Adds regression tests for view-data-* usage without explicit view-data. |
| .github/skills/write-tests/SKILL.md | Adds documentation for a “write-tests” skill. |
| .github/skills/verify-tests/SKILL.md | Adds documentation for verifying tests reproduce/fix a bug. |
| .github/skills/try-fix/SKILL.md | Adds documentation for trying one alternative fix approach. |
| .github/skills/fix-issue/SKILL.md | Adds a large “fix-issue” workflow skill definition. |
| .github/skills/fix-issue/tests/test-skill-definition.sh | Adds bash tests validating the fix-issue skill definition content. |
| .github/skills/fix-issue/tests/test-ai-summary-comment.sh | Adds bash tests for the AI summary comment scripts. |
| .github/skills/ai-summary-comment/SKILL.md | Adds documentation for posting/updating a unified AI summary comment. |
| .github/skills/ai-summary-comment/scripts/post-ai-summary-comment.sh | Adds a script to post/update a PR comment by loading phase outputs and composing nested <details> sections. |
…-data-* prefix attributes When using <partial name="_Partial" view-data-key="value" /> without explicitly setting the view-data attribute, the Razor runtime tried to add items to a null ViewData dictionary, causing NullReferenceException. Initialize ViewData from ViewContext.ViewData in the ViewContext property setter so that view-data-* prefix attributes can be populated. When ViewData is explicitly set via the view-data attribute, the property initializer runs after ViewContext and overrides this value. The copy ensures the parent ViewData is not contaminated. Fixes dotnet#9736 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
c656b40 to
aa95d04
Compare
iamteamstar
approved these changes
Mar 2, 2026
iamteamstar
left a comment
There was a problem hiding this comment.
i like your classes naming. very available. aprrove.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
🤖 AI Summary
🔍 Automated Fix Report
🔍 Pre-Flight — Context & Validation
Issue: #9736 — Partial Tag Helper
view-data-*attributes have nullViewDataArea:
src/Mvc/Mvc.TagHelpers/Root Cause:
PartialTagHelper.ViewDatais initialized as a newViewDataDictionaryin the constructor, but it's not connected to the parentViewContext.ViewData. Whenview-data-*attributes are set, they write into this disconnected dictionary, so the data never reaches the partial view.Classification: Bug — initialization ordering issue
🧪 Test — Bug Reproduction
Test File:
src/Mvc/Mvc.TagHelpers/test/PartialTagHelperTest.csTest Added:
ProcessAsync_UsesViewDataFromViewContext_WhenViewDataPrefixAttributesSet— verifies thatview-data-*prefix attributes are accessible to the partial view viaViewData.Strategy: Set
ViewContexton the tag helper, then add aview-data-messageattribute, and verify the ViewData dictionary contains the expected key-value pair.🚦 Gate — Test Verification & Regression
Gate Result: ✅ All 24 PartialTagHelper tests pass
Test Command:
Regression: No failures in existing test suite.
🔧 Fix — Analysis & Comparison (✅ 2 passed, ❌ 2 failed)
Fix: Ensure ViewData is initialized from ViewContext.ViewData before view-data-* prefix attributes are bound.
✅ Attempt 0: PASS
Approach: Initialize ViewData in ViewContext setter with null-guard.
Added a
_viewContextbacking field. In the setter, whenViewDatais null andViewContext.ViewDatais available, initializeViewData = new ViewDataDictionary(value.ViewData). This ensuresview-data-*attributes work sinceViewContextis set during activation before markup attributes.📄 Diff
❌ Attempt 1: FAIL
Approach: Initialize ViewData at the start of ProcessAsync with
ViewData ??= new ViewDataDictionary(ViewContext.ViewData).This fails because
view-data-*prefix attributes are bound toViewDataby the tag helper infrastructure beforeProcessAsyncis called. By the time we initialize it in ProcessAsync, the attribute values have already been lost.📄 Diff
❌ Attempt 2: FAIL
Approach: Override
Init(TagHelperContext)to initialize ViewData from ViewContext.Init runs after activation (ViewContext set) but before attribute binding (view-data-* processed). However, this adds new public API surface requiring PublicAPI.Unshipped.txt updates, and the API analyzer signature mismatch was difficult to resolve.
📄 Diff
✅ Attempt 3: PASS
Approach: Lazy-initialize ViewData in its getter using
??=with ViewContext.ViewData.Added
_viewDatabacking field. ViewData getter uses??=to lazily create aViewDataDictionaryfromViewContext.ViewDatawhen first accessed. The setter allows explicit override. No changes to ViewContext property needed.📄 Diff