问题描述
因此,随着发布了asp.net core 3.0和blazor 1.0,我开始对blazor进行一些实际工作.将Blazor组件代码拆分为后面的代码时,我正在使用以下
So with a release of asp.net core 3.0 and blazor 1.0 I started doing some actual work with blazor. When splitting Blazor component code into code behind I am using the following
public class LogoutModel : BlazorComponent
{
}
不幸的是BlazorComponent不再存在,所以我转到ComponentBase.不确定此更改何时发生..
Unfortunatelly BlazorComponent does not exist anymore, so I move to ComponentBase. Not sure when did this change took place..
现在我的其余代码看起来像这样
Now the rest of my code looks like this
public class LogoutModel : ComponentBase
{
protected override async Task OnInitializedAsync()
{
}
protected override async Task OnParametersSetAsync()
{
}
}
我注意到的是生命周期方法按以下顺序执行OnInitializedAsync()OnParametersSetAsync()OnInitializedAsync()OnParametersSetAsync()
What i notice is that life cycle methods are executed in the following orderOnInitializedAsync()OnParametersSetAsync()OnInitializedAsync()OnParametersSetAsync()
我不确定每个方法为什么执行两次.
I am not really sure why is each method executed twice.
这就是我的Blazor文件的样子
This is what my Blazor file looks like
@page "/account/logout"
@inherits LogoutModel
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title></title>
</head>
<body>
Logout page
</body>
</html>
推荐答案
我对一个新的blazorserver
项目进行了测试,记录了调用生命周期方法的时间,并获得了以下输出:
I did a test with a fresh new blazorserver
project, logging when lifecycle methods are called, and got this output:
info: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[0]
User profile is available. Using 'C:\Users\Alsein\AppData\Local\ASP.NET\DataProtection-Keys' as key repository and Windows DPAPI to encrypt keys at rest.
info: Microsoft.Hosting.Lifetime[0]
Now listening on: https://localhost:5001
info: Microsoft.Hosting.Lifetime[0]
Now listening on: http://localhost:5000
info: Microsoft.Hosting.Lifetime[0]
Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
Hosting environment: Development
info: Microsoft.Hosting.Lifetime[0]
Content root path: D:\repos\HelloWorld
info: Microsoft.AspNetCore.Hosting.Diagnostics[1]
Request starting HTTP/2 GET https://localhost:5001/
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[0]
Executing endpoint '/_Host'
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[3]
Route matched with {page = "/_Host"}. Executing page /_Host
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[103]
Executing an implicit handler method - ModelState is Valid
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[104]
Executed an implicit handler method, returned result Microsoft.AspNetCore.Mvc.RazorPages.PageResult.
crit: HelloWorld.MyBase[0]
OnInitializedAsync
crit: HelloWorld.MyBase[0]
OnParameterSetAsync
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[4]
Executed page /_Host in 122.3724ms
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[1]
Executed endpoint '/_Host'
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
Request finished in 216.7341ms 200 text/html; charset=utf-8
info: Microsoft.AspNetCore.Hosting.Diagnostics[1]
Request starting HTTP/2 GET https://localhost:5001/css/site.css
info: Microsoft.AspNetCore.Hosting.Diagnostics[1]
Request starting HTTP/2 GET https://localhost:5001/_framework/blazor.server.js
info: Microsoft.AspNetCore.Hosting.Diagnostics[1]
Request starting HTTP/2 GET https://localhost:5001/css/bootstrap/bootstrap.min.css
info: Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware[2]
Sending file. Request path: '/css/site.css'. Physical path: 'D:\repos\HelloWorld\wwwroot\css\site.css'
info: Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware[2]
Sending file. Request path: '/_framework/blazor.server.js'. Physical path: 'N/A'
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
Request finished in 44.733000000000004ms 200 text/css
info: Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware[2]
Sending file. Request path: '/css/bootstrap/bootstrap.min.css'. Physical path: 'D:\repos\HelloWorld\wwwroot\css\bootstrap\bootstrap.min.css'
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
Request finished in 55.3613ms 200 text/css
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
Request finished in 55.569900000000004ms 200 application/javascript
info: Microsoft.AspNetCore.Hosting.Diagnostics[1]
Request starting HTTP/2 GET https://localhost:5001/css/open-iconic/font/css/open-iconic-bootstrap.min.css
info: Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware[2]
Sending file. Request path: '/css/open-iconic/font/css/open-iconic-bootstrap.min.css'. Physical path: 'D:\repos\HelloWorld\wwwroot\css\open-iconic\font\css\open-iconic-bootstrap.min.css'
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
Request finished in 4.5189ms 200 text/css
info: Microsoft.AspNetCore.Hosting.Diagnostics[1]
Request starting HTTP/2 POST https://localhost:5001/_blazor/negotiate text/plain;charset=UTF-8 0
info: Microsoft.AspNetCore.Hosting.Diagnostics[1]
Request starting HTTP/2 GET https://localhost:5001/css/open-iconic/font/fonts/open-iconic.woff
info: Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware[2]
Sending file. Request path: '/css/open-iconic/font/fonts/open-iconic.woff'. Physical path: 'D:\repos\HelloWorld\wwwroot\css\open-iconic\font\fonts\open-iconic.woff'
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
Request finished in 4.3562ms 200 application/font-woff
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[0]
Executing endpoint '/_blazor/negotiate'
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[1]
Executed endpoint '/_blazor/negotiate'
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
Request finished in 24.7409ms 200 application/json
info: Microsoft.AspNetCore.Hosting.Diagnostics[1]
Request starting HTTP/1.1 GET https://localhost:5001/_blazor?id=7oyJvbydrUy9tqlsH_DHzQ
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[0]
Executing endpoint '/_blazor'
crit: HelloWorld.MyBase[0]
OnInitializedAsync
crit: HelloWorld.MyBase[0]
OnParameterSetAsync
从结果中我们可以看到,该组件被加载了两次.
From the result we can see that, the component is loaded twice.
- 第一次由
/_Host
请求和处理页面时,直接将其作为简单的Mvc组件加载,必须使用_Host.cshtml
中的以下代码指定该页面,该代码首次调用生命周期方法:
- The first time it was loaded as a simple Mvc component directly when the page is requested and handled by
/_Host
which must be specified with the following code in_Host.cshtml
, which calls the lifecycle methods for the first time:
@(await Html.RenderComponentAsync<App>(RenderMode.ServerPrerendered))
-
然后加载包括
blazor.server.js
的资源.Then resources are loaded including
blazor.server.js
.然后,blazor应用程序开始渲染.
Then the blazor app starts rendering.
然后将该组件作为blazor组件加载,在其中第二次调用生命周期方法.
Then the component is loaded as a blazor component, where the lifecycle methods are called for the second time.
尝试将
RenderMode.ServerPrerendered
替换为RenderMode.Server
,然后其行为将与预期的一样,即生命周期方法仅被调用一次(blazor应用程序启动时).Try replacing
RenderMode.ServerPrerendered
withRenderMode.Server
, then it behaves as expected, which is that the lifecycle methods are only called for once (when the blazor app starts).结论:默认的
RenderMode
是ServerPrerendered
,这意味着Mvc可以将组件呈现为静态内容,以便在blazor应用程序下载并启动之前显示页面内容,然后在blazor应用程序启动时,它将接管页面内容.对于用户体验而言,这必须是一种变通方法,即浏览器用户可以等待更少的时间来查看内容.Conclusion:The default
RenderMode
isServerPrerendered
which must mean that Mvc could render the components as static contents in order to display the page contents before the blazor app is downloaded and starts, then when the blazor app starts, it takes over the page content. This must be a workaround for user experience that the browser user could wait less time for seeing the contents.这篇关于为什么Blazor生命周期方法要执行两次?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!