Skip to content

Commit 2773e8a

Browse files
dotnet-maestro-botmthalmanSteveSandersonMS
authored
[automated] Merge branch 'release/8.0-rc2' => 'release/8.0' (#50823)
* Handle obsolete InterceptorsPreview with .NET 8 RC2 SDK (#50797) * Quarantine (actually comment out) one of the CanRenderComponentWithPersistedState cases (#50811) See #50810 * Stop processing original response streaming content if user has started navigating away (#50814) * Reproduce #50733 as a failing E2E test * Don't process original request blazor-ssr content if the user has already navigated away * Quarantine (actually comment out) one of the CanRenderComponentWithPersistedState cases See #50810 * Update EventTest.cs * Disable another flaky test --------- Co-authored-by: Matt Thalman <[email protected]> Co-authored-by: Steve Sanderson <[email protected]>
1 parent 5dd11ac commit 2773e8a

File tree

6 files changed

+64
-4
lines changed

6 files changed

+64
-4
lines changed

src/Components/Endpoints/src/Rendering/EndpointHtmlRenderer.Streaming.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ private void SendBatchAsStreamingUpdate(in RenderBatch renderBatch, TextWriter w
118118
}
119119

120120
// Now process the list, skipping any we've already visited in an earlier iteration
121+
var isEnhancedNavigation = IsProgressivelyEnhancedNavigation(_httpContext.Request);
121122
for (var i = 0; i < componentIdsInDepthOrder.Length; i++)
122123
{
123124
var componentId = componentIdsInDepthOrder[i].ComponentId;
@@ -132,7 +133,7 @@ private void SendBatchAsStreamingUpdate(in RenderBatch renderBatch, TextWriter w
132133
// as it is being written out.
133134
writer.Write($"<template blazor-component-id=\"");
134135
writer.Write(componentId);
135-
writer.Write("\">");
136+
writer.Write(isEnhancedNavigation ? "\" enhanced-nav=\"true\">" : "\">");
136137

137138
// We don't need boundary markers at the top-level since the info is on the <template> anyway.
138139
WriteComponentHtml(componentId, writer, allowBoundaryMarkers: false);

src/Components/Web.JS/dist/Release/blazor.web.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Components/Web.JS/src/Rendering/StreamingRendering.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33

44
import { SsrStartOptions } from '../Platform/SsrStartOptions';
5-
import { NavigationEnhancementCallbacks, performEnhancedPageLoad, replaceDocumentWithPlainText } from '../Services/NavigationEnhancement';
5+
import { NavigationEnhancementCallbacks, hasNeverStartedAnyEnhancedPageLoad, performEnhancedPageLoad, replaceDocumentWithPlainText } from '../Services/NavigationEnhancement';
66
import { isWithinBaseUriSpace, toAbsoluteUri } from '../Services/NavigationUtils';
77
import { synchronizeDomContent } from './DomMerging/DomSync';
88

@@ -36,7 +36,14 @@ class BlazorStreamingUpdate extends HTMLElement {
3636
if (node instanceof HTMLTemplateElement) {
3737
const componentId = node.getAttribute('blazor-component-id');
3838
if (componentId) {
39-
insertStreamingContentIntoDocument(componentId, node.content);
39+
// For enhanced nav page loads, we automatically cancel the response stream if another enhanced nav supersedes it. But there's
40+
// no way to cancel the original page load. So, to avoid continuing to process <blazor-ssr> blocks from the original page load
41+
// if an enhanced nav supersedes it, we must explicitly check whether this content is from the original page load, and if so,
42+
// ignore it if any enhanced nav has started yet. Fixes https://github.com/dotnet/aspnetcore/issues/50733
43+
const isFromEnhancedNav = node.getAttribute('enhanced-nav') === 'true';
44+
if (isFromEnhancedNav || hasNeverStartedAnyEnhancedPageLoad()) {
45+
insertStreamingContentIntoDocument(componentId, node.content);
46+
}
4047
} else {
4148
switch (node.getAttribute('type')) {
4249
case 'redirection':

src/Components/Web.JS/src/Services/NavigationEnhancement.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@ export function isPageLoading() {
4444
return performingEnhancedPageLoad || document.readyState === 'loading';
4545
}
4646

47+
export function hasNeverStartedAnyEnhancedPageLoad() {
48+
return !currentEnhancedNavigationAbortController;
49+
}
50+
4751
export function attachProgressivelyEnhancedNavigationListener(callbacks: NavigationEnhancementCallbacks) {
4852
navigationEnhancementCallbacks = callbacks;
4953
document.addEventListener('click', onDocumentClick);

src/Components/test/E2ETest/ServerRenderingTests/StreamingRenderingTest.cs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,4 +222,50 @@ static async Task<string> BandwidthThrottledGet(string url, int chunkLength, int
222222
}
223223
}
224224
}
225+
226+
[Theory]
227+
[InlineData(false)]
228+
[InlineData(true)]
229+
public async void StopsProcessingStreamingOutputFromPreviousRequestAfterEnhancedNav(bool duringEnhancedNavigation)
230+
{
231+
IWebElement originalH1Elem;
232+
233+
if (duringEnhancedNavigation)
234+
{
235+
Navigate($"{ServerPathBase}/nav");
236+
originalH1Elem = Browser.Exists(By.TagName("h1"));
237+
Browser.Equal("Hello", () => originalH1Elem.Text);
238+
Browser.Exists(By.TagName("nav")).FindElement(By.LinkText("Streaming")).Click();
239+
}
240+
else
241+
{
242+
Navigate($"{ServerPathBase}/streaming");
243+
originalH1Elem = Browser.Exists(By.TagName("h1"));
244+
}
245+
246+
// Initial "waiting" state
247+
Browser.Equal("Streaming Rendering", () => originalH1Elem.Text);
248+
var getStatusText = () => Browser.Exists(By.Id("status"));
249+
var getDisplayedItems = () => Browser.FindElements(By.TagName("li"));
250+
var addItemsUrl = Browser.FindElement(By.Id("add-item-link")).GetDomProperty("href");
251+
var endResponseUrl = Browser.FindElement(By.Id("end-response-link")).GetDomProperty("href");
252+
Assert.Equal("Waiting for more...", getStatusText().Text);
253+
Assert.Empty(getDisplayedItems());
254+
Assert.StartsWith("http", addItemsUrl);
255+
256+
// Navigate away using enhanced nav, before the response is completed
257+
Browser.Exists(By.TagName("nav")).FindElement(By.LinkText("Streaming with interactivity")).Click();
258+
Browser.Equal("Streaming Rendering with Interactivity", () => originalH1Elem.Text);
259+
var statusElem = Browser.FindElement(By.Id("status"));
260+
Assert.Equal("Not streaming", statusElem.Text);
261+
262+
// Now if the earlier navigation produces more output, we do *not* add it to the page
263+
var addItemsOutput = await new HttpClient().GetStringAsync(addItemsUrl);
264+
Assert.Equal("Added item", addItemsOutput);
265+
await Task.Delay(1000); // Make sure we would really have seen the UI change by now if it was going to
266+
Browser.Equal("Not streaming", () => statusElem.Text); // It didn't get removed from the doc, nor was its text updated
267+
268+
// Tidy up
269+
await new HttpClient().GetAsync(endResponseUrl);
270+
}
225271
}

src/Identity/Core/src/Microsoft.AspNetCore.Identity.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@
99
<IsPackable>false</IsPackable>
1010
<IsTrimmable>true</IsTrimmable>
1111
<EnableRequestDelegateGenerator>true</EnableRequestDelegateGenerator>
12+
<!-- TODO: Remove InterceptorsPreview feature after 8.0 RC2 SDK is used for build -->
1213
<Features>$(Features);InterceptorsPreview</Features>
14+
<InterceptorsPreviewNamespaces>$(InterceptorsPreviewNamespaces);Microsoft.AspNetCore.Http.Generated</InterceptorsPreviewNamespaces>
1315
</PropertyGroup>
1416

1517
<ItemGroup>

0 commit comments

Comments
 (0)