-
Notifications
You must be signed in to change notification settings - Fork 10.5k
Follow-up: Improve stopping renderer, fix identity template #61633
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 10 commits
e54bca3
112ba26
3438822
129d180
96f1e6e
70dd508
d33515b
ae715c9
0a6088d
085a3bd
80925ac
3c28ae7
2e4756c
a2c439f
38eb544
2b13780
4f9e9ff
7a21ae8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -46,6 +46,21 @@ public EndpointHtmlRendererTest() | |
renderer = GetEndpointHtmlRenderer(); | ||
} | ||
|
||
[Fact] | ||
public async Task DoesNotRenderChildAfterRendererStopped() | ||
{ | ||
renderer.SignalRendererToFinishRendering(); | ||
|
||
var httpContext = GetHttpContext(); | ||
var writer = new StringWriter(); | ||
|
||
var result = await renderer.PrerenderComponentAsync(httpContext, typeof(SimpleComponent), null, ParameterView.Empty); | ||
await renderer.Dispatcher.InvokeAsync(() => result.WriteTo(writer, HtmlEncoder.Default)); | ||
var content = writer.ToString(); | ||
|
||
Assert.DoesNotContain("Hello from SimpleComponent", content); | ||
} | ||
|
||
Comment on lines
+49
to
+63
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The more interesting case here is where you have something like
|
||
[Fact] | ||
public async Task CanRender_ParameterlessComponent_ClientMode() | ||
{ | ||
|
@@ -1756,6 +1771,7 @@ private TestEndpointHtmlRenderer GetEndpointHtmlRenderer(IServiceProvider servic | |
|
||
private class TestEndpointHtmlRenderer : EndpointHtmlRenderer | ||
{ | ||
private bool _rendererIsStopped = false; | ||
public TestEndpointHtmlRenderer(IServiceProvider serviceProvider, ILoggerFactory loggerFactory) : base(serviceProvider, loggerFactory) | ||
{ | ||
} | ||
|
@@ -1764,6 +1780,20 @@ internal int TestAssignRootComponentId(IComponent component) | |
{ | ||
return base.AssignRootComponentId(component); | ||
} | ||
public void SignalRendererToFinishRendering() | ||
{ | ||
// sets a deferred stop on the renderer, which will have an effect after the current batch is completed | ||
_rendererIsStopped = true; | ||
} | ||
|
||
protected override void ProcessPendingRender() | ||
{ | ||
if (_rendererIsStopped) | ||
{ | ||
return; | ||
} | ||
base.ProcessPendingRender(); | ||
} | ||
ilonatommy marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
private HttpContext GetHttpContext(HttpContext context = null) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,6 +18,8 @@ internal sealed partial class RemoteNavigationManager : NavigationManager, IHost | |
private IJSRuntime _jsRuntime; | ||
private bool? _navigationLockStateBeforeJsRuntimeAttached; | ||
private const string _enableThrowNavigationException = "Microsoft.AspNetCore.Components.Endpoints.NavigationManager.EnableThrowNavigationException"; | ||
|
||
[FeatureSwitchDefinition("Microsoft.AspNetCore.Components.Endpoints.NavigationManager.EnableThrowNavigationException")] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this used to get the value replaced based on There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No, this is compile-time attribute that can be helpful in trimming or Roslyn analysis. |
||
private static bool _throwNavigationException => | ||
AppContext.TryGetSwitch(_enableThrowNavigationException, out var switchValue) && switchValue; | ||
private Func<string, Task>? _onNavigateTo; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
@if(throwException) | ||
{ | ||
throw new InvalidOperationException("Child component UI exception: redirection should have stopped renderer."); | ||
} | ||
|
||
@code { | ||
[Parameter] | ||
public int Delay { get; set; } | ||
|
||
private bool throwException { get; set; } | ||
|
||
private string message = string.Empty; | ||
|
||
protected override async Task OnInitializedAsync() | ||
{ | ||
await Task.Yield(); | ||
_ = ScheduleRenderingExceptionAfterDelay(); | ||
} | ||
|
||
private async Task ScheduleRenderingExceptionAfterDelay() | ||
{ | ||
// This update should not happen if the renderer is stopped | ||
await Task.Delay(Delay); | ||
throwException = true; | ||
StateHasChanged(); | ||
} | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
@page "/stopping-renderer" | ||
@inject NavigationManager NavigationManager | ||
|
||
<p>Parent content</p> | ||
<AsyncComponent @rendermode="@RenderModeHelper.GetRenderMode(CurrentRenderMode)" Delay="@Delay" /> | ||
|
||
@code { | ||
[Parameter, SupplyParameterFromQuery(Name = "destination")] | ||
public string Destination { get; set; } = string.Empty; | ||
|
||
[Parameter, SupplyParameterFromQuery(Name = "renderMode")] | ||
public string? RenderModeStr { get; set; } | ||
|
||
[Parameter, SupplyParameterFromQuery(Name = "delay")] | ||
public int Delay { get; set; } | ||
|
||
private RenderModeId CurrentRenderMode => RenderModeHelper.ParseRenderMode(RenderModeStr); | ||
|
||
protected override Task OnInitializedAsync() | ||
{ | ||
if (!string.IsNullOrEmpty(Destination)) | ||
{ | ||
NavigationManager.NavigateTo(Destination); | ||
} | ||
return Task.CompletedTask; | ||
} | ||
} |
Uh oh!
There was an error while loading. Please reload this page.