Skip to content

Commit 5c60dd3

Browse files
csharpfritzCopilot
andcommitted
docs: Add ContosoUniversity Run 07 migration report
- 40/40 tests passing (100%) - Layer 1: 0.99s, Layer 2: 0.40s - Documents DetailsView BoundField incompatibility - Documents Playwright timing for Blazor Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent f08c7a6 commit 5c60dd3

1 file changed

Lines changed: 148 additions & 0 deletions

File tree

  • dev-docs/migration-tests/contosouniversity-run07-2026-03-09
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
# ContosoUniversity Migration Run 07
2+
3+
**Date:** 2026-03-09
4+
**Branch:** `squad/audit-docs-perf`
5+
**Commit:** `f08c7a6f`
6+
**Score:** **40/40 (100%)**
7+
8+
## Executive Summary
9+
10+
Run 07 of the ContosoUniversity migration achieved 100% acceptance test passage (40/40). The migration scripts (Layer 1 + Layer 2) completed in under 2 seconds total. Manual fixes required ~20 minutes, primarily addressing a BWFC DetailsView incompatibility and Blazor circuit timing issues in tests.
11+
12+
## Timing
13+
14+
| Phase | Duration | Notes |
15+
|-------|----------|-------|
16+
| **Layer 1 (markup)** | 0.99 seconds | 72 transforms, 6 files |
17+
| **Layer 2 (code-behind)** | 0.40 seconds | 7 transforms |
18+
| **Manual fixes** | ~20 minutes | Build errors, model fixes, test timing |
19+
| **Total automated** | **1.39 seconds** | |
20+
21+
## Test Results
22+
23+
| Category | Passed | Failed | Notes |
24+
|----------|--------|--------|-------|
25+
| About Page | 5/5 | 0 | Enrollment stats display |
26+
| Instructors Page | 5/5 | 0 | GridView with sorting |
27+
| Courses Page | 6/6 | 0 | Search + DetailsView fix |
28+
| Students Page | 9/9 | 0 | CRUD operations |
29+
| Navigation | 7/7 | 0 | Routing + nav links |
30+
| Home Page | 8/8 | 0 | Welcome page |
31+
| **TOTAL** | **40/40** | **0** | **100%** |
32+
33+
## Issues Discovered & Fixed
34+
35+
### 1. DetailsView BoundField Incompatibility (Critical)
36+
37+
**Problem:** BWFC `DetailsView` uses an internal field system (`DetailsViewField` subclasses) rather than the standard `BoundField` component used by `GridView`. Placing `BoundField` inside `<Fields>` causes:
38+
```
39+
NullReferenceException: Object reference not set to an instance of an object.
40+
at BlazorWebFormsComponents.BaseColumn`1.OnInitialized()
41+
```
42+
43+
**Root Cause:** `BoundField` looks for a `CascadingParameter(Name = "ColumnCollection")` but `DetailsView` provides `DetailsViewFieldCollection` instead.
44+
45+
**Solution:** Replaced DetailsView with plain HTML table:
46+
```razor
47+
<!-- Before (broken) -->
48+
<DetailsView ID="dtlCourses" DataItem="_selectedCourse">
49+
<Fields>
50+
<BoundField DataField="CourseID" HeaderText="Course ID" />
51+
</Fields>
52+
</DetailsView>
53+
54+
<!-- After (working) -->
55+
<table id="dtlCourses" class="details">
56+
<tr><td>Course ID</td><td>@_selectedCourse.CourseID</td></tr>
57+
</table>
58+
```
59+
60+
**Recommendation:** Document that DetailsView `<Fields>` parameter expects `DetailsViewAutoField` or custom implementations, NOT `BoundField`.
61+
62+
### 2. Button OnClick Handler Signature
63+
64+
**Problem:** Button `OnClick` handlers in InteractiveServer mode need `MouseEventArgs` parameter:
65+
```csharp
66+
// Wrong - causes EventCallback type mismatch
67+
private async Task SearchCourseByName() { }
68+
69+
// Correct
70+
private async Task SearchCourseByName(MouseEventArgs args) { }
71+
```
72+
73+
**Solution:** Added `using Microsoft.AspNetCore.Components.Web` and `MouseEventArgs` to handler signatures.
74+
75+
### 3. Nullable String Properties
76+
77+
**Problem:** Database has NULL values but models had non-nullable `string` with `= ""` initializers, causing `SqlNullValueException`.
78+
79+
**Solution:** Changed all string properties to `string?`:
80+
```csharp
81+
public string? CourseName { get; set; }
82+
```
83+
84+
### 4. LINQ Contains with Null Check
85+
86+
**Problem:** `Contains()` query on nullable string column fails:
87+
```csharp
88+
// Wrong
89+
c.CourseName.Contains(_searchCourse)
90+
91+
// Correct
92+
c.CourseName != null && c.CourseName.Contains(_searchCourse)
93+
```
94+
95+
### 5. Playwright Test Timing for Blazor
96+
97+
**Problem:** Tests for InteractiveServer pages fail because Blazor SignalR circuit isn't established before interactions.
98+
99+
**Solution:** Added explicit waits:
100+
```csharp
101+
await page.WaitForLoadStateAsync(LoadState.NetworkIdle);
102+
await page.WaitForTimeoutAsync(1000); // Wait for Blazor circuit
103+
// ... interact ...
104+
await page.WaitForTimeoutAsync(500); // Wait for re-render
105+
```
106+
107+
## Files Modified
108+
109+
### New Files Created
110+
- `Models/ContosoUniversityContext.cs` - EF Core DbContext with SQL Server
111+
- `Pages/About.razor` + `.cs` - About page with enrollment stats
112+
- `Pages/Courses.razor` + `.cs` - Courses page with search
113+
- `Pages/Home.razor` - Home page
114+
- `Pages/Instructors.razor` + `.cs` - Instructors with GridView sorting
115+
- `Pages/Students.razor` + `.cs` - Student CRUD operations
116+
- `appsettings.Development.json` - Detailed error logging
117+
118+
### Modified Files
119+
- `ContosoUniversity.csproj` - Added EF Core SQL Server package
120+
- `Program.cs` - DbContextFactory, URL rewriting, middleware
121+
- `_Imports.razor` - Added model namespace
122+
- `Components/Layout/MainLayout.razor` - Fixed nav links
123+
124+
### Test Files Modified
125+
- `src/ContosoUniversity.AcceptanceTests/CoursesPageTests.cs` - Added Blazor circuit timing waits
126+
127+
## Key Learnings
128+
129+
1. **BWFC DetailsView is not column-compatible with GridView** - They share similar syntax but use different internal field systems
130+
2. **InteractiveServer handlers need MouseEventArgs** - EventCallback<MouseEventArgs> requires the parameter
131+
3. **Playwright tests for Blazor need explicit timing** - NetworkIdle isn't enough; must wait for SignalR circuit
132+
4. **SQL Server nullable columns need nullable C# types** - Even with empty string initializers, EF Core can return null
133+
134+
## Comparison to Previous Runs
135+
136+
| Run | Score | Key Improvement |
137+
|-----|-------|----------------|
138+
| Run 01-03 | 31/40 (77.5%) | Initial migration |
139+
| Run 04 | 36/40 (90%) | URL rewriting |
140+
| Run 05 | 40/40 (100%) | SQL Server, InteractiveServer |
141+
| **Run 07** | **40/40 (100%)** | DetailsView fix, test timing |
142+
143+
## Recommendations
144+
145+
1. **Update migration skills** to document DetailsView limitations
146+
2. **Add DetailsViewBoundField component** to BWFC library (or document the limitation)
147+
3. **Update Layer 2 script** to add MouseEventArgs to button handlers automatically
148+
4. **Add Blazor circuit wait helper** to acceptance test infrastructure

0 commit comments

Comments
 (0)