Skip to content

Commit 056808f

Browse files
committed
Merge in 'release/8.0-rc2' changes
2 parents ffb9f0b + e1f66a2 commit 056808f

File tree

4 files changed

+62
-0
lines changed

4 files changed

+62
-0
lines changed

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,17 @@ private void SendBatchAsStreamingUpdate(in RenderBatch renderBatch, TextWriter w
127127
continue;
128128
}
129129

130+
// Of the components that updated, we want to emit the roots of all the streaming subtrees, and not
131+
// any non-streaming ancestors. There's no point emitting non-streaming ancestor content since there
132+
// are no markers in the document to receive it. Also we don't want to call WriteComponentHtml for
133+
// nonstreaming ancestors, as that would make us skip over their descendants who may in fact be the
134+
// roots of streaming subtrees.
135+
var componentState = (EndpointComponentState)GetComponentState(componentId);
136+
if (!componentState.StreamRendering)
137+
{
138+
continue;
139+
}
140+
130141
// This format relies on the component producing well-formed markup (i.e., it can't have a
131142
// </template> at the top level without a preceding matching <template>). Alternatively we
132143
// could look at using a custom TextWriter that does some extra encoding of all the content

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,4 +268,11 @@ public async void StopsProcessingStreamingOutputFromPreviousRequestAfterEnhanced
268268
// Tidy up
269269
await new HttpClient().GetAsync(endResponseUrl);
270270
}
271+
272+
[Fact]
273+
public void CanStreamDirectlyIntoSectionContentConnectedToNonStreamingOutlet()
274+
{
275+
Navigate($"{ServerPathBase}/streaming-with-sections");
276+
Browser.Equal("This is some streaming content", () => Browser.Exists(By.Id("streaming-message")).Text);
277+
}
271278
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
@page "/streaming-with-sections"
2+
@using Microsoft.AspNetCore.Components.Sections
3+
4+
<h1>Streaming with sections</h1>
5+
6+
<p>
7+
If a section outlet is rendered from a nonstreaming component, but the section content comes from a streaming component,
8+
then we should still see streaming updates arriving in the section outlet.
9+
</p>
10+
11+
<p>
12+
This component is not streaming, but it has a child that does stream, and supplies content back here to the parent.
13+
</p>
14+
15+
<fieldset>
16+
<legend>Section outlet in nonstreaming component</legend>
17+
<SectionOutlet SectionName="streaming-outlet" />
18+
</fieldset>
19+
20+
<StreamingWithSectionsContentSupplier />
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
@using Microsoft.AspNetCore.Components.Sections
2+
@attribute [StreamRendering]
3+
4+
@*
5+
For the test to be relevant, it's important that the streaming output comes from *this component* and not some descendant.
6+
This is to ensure we correctly represent issue https://github.com/dotnet/aspnetcore/issues/50804
7+
If it's a descendant that streams, the descendant simply lives within the SectionOutlet and encapsulates its own streaming,
8+
and sections aren't really involved. But if the streaming output goes *directly* into SectionContent, then we're in a more
9+
challenging situation because we need the SectionOutletContentRenderer to become streaming.
10+
*@
11+
12+
<SectionContent SectionName="streaming-outlet">
13+
<span id="streaming-message">@message</span>
14+
</SectionContent>
15+
16+
@code {
17+
string message = "Starting...";
18+
19+
protected override async Task OnInitializedAsync()
20+
{
21+
await Task.Delay(1000);
22+
message = "This is some streaming content";
23+
}
24+
}

0 commit comments

Comments
 (0)