dotnet / aspnetcore

ASP.NET Core is a cross-platform .NET framework for building modern cloud-based web applications on Windows, Mac, or Linux.
https://asp.net
MIT License
35.23k stars 9.95k forks source link

Custom RouteView Render Is Called Twice in Blazor WASM #33282

Closed ArgoZhang closed 8 months ago

ArgoZhang commented 3 years ago

Custom RouteView Render Is Called Twice in Blazor WASM

To Reproduce

App.razor code

<Router AppAssembly="@typeof(MainLayout).Assembly" PreferExactMatches="@true">
    <Found Context="routeData">
        <TestRouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
    </Found>
    <NotFound>
        <LayoutView Layout="@typeof(MainLayout)">
            <p>Not Found</p>
        </LayoutView>
    </NotFound>
</Router>

TestRouteView.cs code

using Microsoft.AspNetCore.Components;
using Microsoft.Extensions.Logging;
using System;
using System.Diagnostics.CodeAnalysis;

namespace WebApplication1
{
    public class TestRouteView : RouteView
    {
        [Inject]
        [NotNull]
        private ILogger<TestRouteView>? Logger { get; set; }

        /// <summary>
        ///
        /// </summary>
        /// <param name="builder"></param>
        protected override void Render(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder builder)
        {
            Logger.LogInformation($"{DateTime.Now}: 1");
            base.Render(builder);
            Logger.LogInformation($"{DateTime.Now}: 2");
        }
    }
}

Program.cs

using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Net.Http;
using System.Threading.Tasks;

namespace WebApplication1
{
    public class Program
    {
        public static async Task Main(string[] args)
        {
            var builder = WebAssemblyHostBuilder.CreateDefault(args);
            builder.RootComponents.Add<App>("#app");

            builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });

            await builder.Build().RunAsync();
        }
    }
}

Exceptions (if any)

no exceptions

Logger Information

image

Further technical details

Runtime Environment: OS Name: Windows OS Version: 10.0.17763 OS Platform: Windows RID: win10-x64 Base Path: C:\Program Files\dotnet\sdk\5.0.300\

Host (useful for support): Version: 5.0.6 Commit: 478b2f8c0e

.NET SDKs installed: 5.0.203 [C:\Program Files\dotnet\sdk] 5.0.300 [C:\Program Files\dotnet\sdk]

.NET runtimes installed: Microsoft.AspNetCore.All 2.1.28 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All] Microsoft.AspNetCore.App 2.1.28 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 3.1.15 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 5.0.6 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.NETCore.App 2.1.28 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 3.1.15 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 5.0.6 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.WindowsDesktop.App 3.1.15 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 5.0.6 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]

To install additional .NET runtimes or SDKs: https://aka.ms/dotnet-download


- The IDE (VS / VS Code/ VS4Mac) you're running on, and its version
Microsoft Visual Studio Enterprise 2019
Version 16.10.0
ghost commented 3 years ago

Thanks for contacting us.

We're moving this issue to the Next sprint planning milestone for future evaluation / consideration. We would like to keep this around to collect more feedback, which can help us with prioritizing this work. We will re-evaluate this issue, during our next planning meeting(s). If we later determine, that the issue has no community involvement, or it's very rare and low-impact issue, we will close it - so that the team can focus on more important and high impact issues. To learn more about what to expect next and how this issue will be handled you can read more about our triage process here.

ghost commented 3 years ago

We've moved this issue to the Backlog milestone. This means that it is not going to be worked on for the coming release. We will reassess the backlog following the current release and consider this item at that time. To learn more about our issue management process and to have better expectation regarding different types of issues you can read our Triage Process.

dezared commented 3 years ago

Is there any information about this happening, and is there a workaround?

ArgoZhang commented 3 years ago

@DezareD not yet

javiercn commented 1 year ago

@ArgoZhang could you provide a minimal repro project so that we can be sure we are not missing any detail? Also, could you try first to reproduce this with .NET 6.0 or .NET 7.0 since 5.0 is out of support at this point?

ghost commented 1 year ago

Hi @ArgoZhang. We have added the "Needs: Author Feedback" label to this issue, which indicates that we have an open question for you before we can take further action. This issue will be closed automatically in 7 days if we do not hear back from you by then - please feel free to re-open it if you come back to this issue after that time.

ghost commented 1 year ago

This issue has been automatically marked as stale because it has been marked as requiring author feedback but has not had any activity for 4 days. It will be closed if no further activity occurs within 3 days of this comment. If it is closed, feel free to comment when you are able to provide the additional information and we will re-investigate.

See our Issue Management Policies for more information.

ArgoZhang commented 1 year ago

@javiercn sorry for the delayed reply. please check the repro project. BlazorApp1.zip

vflame commented 1 year ago

This behavior is happening with the default Router as well:

App.razor:

@{
    IncrementAppRazor();
}
<Router AppAssembly="@typeof(App).Assembly">

    <Found Context="routeData">
        @{
            IncrementFound();
        }
        <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
        <FocusOnNavigate RouteData="@routeData" Selector="h1" />

    </Found>
    <NotFound>
        <PageTitle>Not found</PageTitle>
        <LayoutView Layout="@typeof(MainLayout)">
            <p role="alert">Sorry, there's nothing at this address.</p>
        </LayoutView>
    </NotFound>
</Router>

@code
{
    public static int invocationCount1;
    public static int invocationCount2;

    public void IncrementAppRazor()
    {
        Interlocked.Increment(ref invocationCount1);
        Console.WriteLine("AppRazor invocations: " + invocationCount1);
    }

    public void IncrementFound()
    {
        Interlocked.Increment(ref invocationCount2);
        Console.WriteLine("Router Found invocations: " + invocationCount2);
    }
}

<component type="typeof(App)" render-mode="Server" /> Output: AppRazor invocations: 1 Router Found invocations: 1 Router Found invocations: 2

<component type="typeof(App)" render-mode="ServerPrerendered" /> Output: AppRazor invocations: 1 Router Found invocations: 1 Router Found invocations: 2 AppRazor invocations: 2 Router Found invocations: 3 Router Found invocations: 4

Guessing that it has to do with the following:

https://github.com/dotnet/aspnetcore/blob/main/src/Components/Components/src/Routing/Router.cs#L246 and https://github.com/dotnet/aspnetcore/blob/main/src/Components/Components/src/Routing/Router.cs#L262 Invoking twice since Refresh is the only place where the Found renderfragment is rendered

mkArtakMSFT commented 9 months ago

Parking under .NET 9 Planning to see if we can prioritize the investigation. Specifically, to understand if this is a bug or happening by-design.

ghost commented 9 months ago

Thanks for contacting us.

We're moving this issue to the .NET 9 Planning milestone for future evaluation / consideration. We would like to keep this around to collect more feedback, which can help us with prioritizing this work. We will re-evaluate this issue, during our next planning meeting(s). If we later determine, that the issue has no community involvement, or it's very rare and low-impact issue, we will close it - so that the team can focus on more important and high impact issues. To learn more about what to expect next and how this issue will be handled you can read more about our triage process here.

mkArtakMSFT commented 8 months ago

Hi. Thanks for contacting us. We're closing this issue as there was not much community interest in this ask for quite a while now. You can learn more about our triage process and how we handle issues by reading our Triage Process writeup.