Skip to content

Commit fc49fe6

Browse files
committed
Solve merge conflict: hard stop in redirection and deferred stop in 404.
1 parent ebdf9a9 commit fc49fe6

File tree

6 files changed

+67
-18
lines changed

6 files changed

+67
-18
lines changed

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,11 @@ private async Task SetNotFoundResponseAsync(string baseUri)
9393
_httpContext.Response.StatusCode = StatusCodes.Status404NotFound;
9494
_httpContext.Response.ContentType = null;
9595
}
96-
SignalRendererToFinishRendering();
96+
97+
// When the application triggers a NotFound event, we continue rendering the current batch.
98+
// However, after completing this batch, we do not want to process any further UI updates,
99+
// as we are going to return a 404 status and discard the UI updates generated so far.
100+
SignalRendererToFinishRenderingAfterCurrentBatch();
97101
}
98102

99103
private async Task OnNavigateTo(string uri)

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

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,12 +183,28 @@ protected override void AddPendingTask(ComponentState? componentState, Task task
183183
base.AddPendingTask(componentState, task);
184184
}
185185

186-
protected override void SignalRendererToFinishRendering()
186+
private void SignalRendererToFinishRenderingAfterCurrentBatch()
187187
{
188+
// sets a deferred stop on the renderer, which will have an effect after the current batch is completed
188189
_rendererIsStopped = true;
190+
}
191+
192+
protected override void SignalRendererToFinishRendering()
193+
{
194+
SignalRendererToFinishRenderingAfterCurrentBatch();
195+
// sets a hard stop on the renderer, which will have an effect immediately
189196
base.SignalRendererToFinishRendering();
190197
}
191198

199+
protected override void ProcessPendingRender()
200+
{
201+
if (_rendererIsStopped)
202+
{
203+
return;
204+
}
205+
base.ProcessPendingRender();
206+
}
207+
192208
// For tests only
193209
internal Task? NonStreamingPendingTasksCompletion;
194210

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,4 +106,17 @@ public void CanRenderNotFoundPageNoStreaming(bool useCustomNotFoundPage)
106106
Assert.Contains("There's nothing here", bodyText);
107107
}
108108
}
109+
110+
[Theory]
111+
[InlineData(true)]
112+
[InlineData(false)]
113+
public void CanRenderNotFoundPageWithStreaming(bool useCustomNotFoundPage)
114+
{
115+
// when streaming started, we always render page under "not-found" path
116+
string query = useCustomNotFoundPage ? "?useCustomNotFoundPage=true" : "";
117+
Navigate($"{ServerPathBase}/streaming-set-not-found{query}");
118+
119+
string expectedTitle = "Default Not Found Page";
120+
Browser.Equal(expectedTitle, () => Browser.Title);
121+
}
109122
}

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

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,21 +22,18 @@ public class StatusCodePagesTest(BrowserFixture browserFixture, BasicTestAppServ
2222
{
2323

2424
[Theory]
25-
[InlineData(false, true)]
26-
[InlineData(true, false)]
2725
[InlineData(false, false)]
28-
public void StatusCodePagesWithReExecution(bool setNotFound, bool streaming)
26+
[InlineData(true, false)]
27+
[InlineData(true, true)]
28+
public void StatusCodePagesWithReExecution(bool streaming, bool responseStarted)
2929
{
3030
string streamingPath = streaming ? "streaming-" : "";
31-
Navigate($"{ServerPathBase}/reexecution/{streamingPath}set-not-found?shouldSet={setNotFound}");
31+
Navigate($"{ServerPathBase}/reexecution/{streamingPath}set-not-found?responseStarted={responseStarted}");
3232

3333
// streaming when response started does not re-execute
34-
string expectedTitle = streaming
34+
string expectedTitle = responseStarted
3535
? "Default Not Found Page"
36-
: setNotFound
37-
? "Re-executed page"
38-
: "Original page";
36+
: "Re-executed page";
3937
Browser.Equal(expectedTitle, () => Browser.Title);
4038
}
41-
4239
}

src/Components/test/testassets/Components.TestServer/RazorComponents/Pages/PageThatSetsNotFound.razor

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,12 @@
1010
@code{
1111
[Parameter]
1212
[SupplyParameterFromQuery(Name = "shouldSet")]
13-
public bool ShouldSet { get; set; } = true;
13+
public bool? ShouldSet { get; set; }
1414

1515
protected override void OnInitialized()
1616
{
17-
if (ShouldSet)
17+
bool shouldSet = ShouldSet ?? true;
18+
if (shouldSet)
1819
{
1920
NavigationManager.NotFound();
2021
}
Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,30 @@
1+
@page "/reexecution/streaming-set-not-found"
12
@page "/streaming-set-not-found"
23
@attribute [StreamRendering]
34
@inject NavigationManager NavigationManager
45

5-
@code{
6+
@code {
7+
[Parameter]
8+
[SupplyParameterFromQuery(Name = "shouldSet")]
9+
public bool? ShouldSet { get; set; }
10+
11+
[Parameter]
12+
[SupplyParameterFromQuery(Name = "responseStarted")]
13+
public bool? ResponseStarted { get; set; }
14+
615
protected override async Task OnInitializedAsync()
716
{
8-
// Simulate some delay before triggering NotFound to start streaming response
9-
await Task.Yield();
10-
NavigationManager.NotFound();
17+
bool shouldSet = ShouldSet ?? true;
18+
bool responseStarted = ResponseStarted ?? true;
19+
if (responseStarted)
20+
{
21+
// Simulate some delay before triggering NotFound to start streaming response
22+
await Task.Yield();
23+
}
24+
25+
if (shouldSet)
26+
{
27+
NavigationManager.NotFound();
28+
}
1129
}
12-
}
30+
}

0 commit comments

Comments
 (0)