Asp.net Blazor工作原理解析

2024-03-12 11:54:42 浏览数 (3)

1 asp.net core中的两种前端文件对比

Razor 标记页(文件扩展名为 .razor)文件中包含了html 代码和cs代码。

asp.net core中前端文件中既有.razor文件也有.cshtml文件。

Razor引擎对于.cshtml文件和.razor文件的解析过程基本上是相似的,但是也有细微的差异。

1.1 razor与cshtml相似性

  • 对于.cshtml文件和.razor文件,Razor引擎都会解析其中的HTML和Razor代码,并将其转换成可执行的C#代码。
  • 无论是.cshtml文件还是.razor文件,它们最终都会被编译成C#类,这些类会负责处理页面逻辑、渲染和与后端交互等任务。

1.2 差异

  • 在ASP.NET Core中,.cshtml文件通常用于创建传统的MVC视图或页面,而.razor文件用于创建基于Blazor的Web组件。
  • .razor文件中的C#代码更加紧密地与HTML代码交织在一起,因为Blazor组件的核心就是将前端的HTML和后端的C#代码封装到同一个文件中。而.cshtml文件中的C#代码通常用于控制视图的动态行为和数据呈现,与HTML代码相对独立。
  • 在Blazor中,.razor文件中的C#代码经常使用基于Razor语法的@符号来嵌入到HTML代码中,而.cshtml文件中的C#代码则使用@符号来标识Razor代码块,但不会嵌入到HTML标记中。

2 razor引擎解析razor/cshtml的过程

2.1 原理概述

Razor引擎的主要作用之一就是将包含HTML和C#代码的Razor标记页文件(扩展名为.razor)编译成C#类代码。这个C#类代码实际上是一个继承自Microsoft.AspNetCore.Components.ComponentBase的组件类,它包含了HTML中的静态内容以及与C#代码交织在一起的动态内容。

在编译过程中,Razor引擎会解析Razor标记页文件中的HTML和Razor代码,将其中的Razor代码转换成对应的C#代码,并将其嵌入到生成的组件类中。Razor引擎的编译过程是将Razor标记页文件中的HTML和C#代码转换成可执行的C#类代码,从而实现了页面逻辑与呈现的分离,同时保留了编写页面逻辑的便利性。

生成的C#类代码会负责处理组件的渲染、事件处理等逻辑,以及与页面中的HTML元素进行交互。

Razor引擎会根据以下规则处理HTML代码:

  1. HTML标记: Razor引擎会将HTML标记识别为静态内容,并将其保留在生成的C#代码中。这意味着HTML标记会以原样保留,并且不会被编译成C#代码的字符串。
  2. Razor代码块: 如果在.razor或.cshtml文件中包含了Razor代码块(以@符号开头),Razor引擎会将其识别为动态代码块,并将其中的C#代码解析并编译成相应的C#语句或表达式。这些动态代码块会嵌入到生成的C#类中,以便在运行时执行。
  3. HTML属性: Razor引擎会识别HTML标记中的属性,并将其解析为C#属性或字段。对于使用@符号绑定的属性,Razor引擎会将其识别为动态属性,并在生成的C#代码中生成相应的属性访问或绑定逻辑。

2.2 示例

这里我们用一个简单的示例来说明Razor引擎解析.razor或.cshtml文件的原理。

假设有如下的.razor文件:

代码语言:razor复制
<h1>Welcome, @Name!</h1>

@if (ShowMessage)
{
    <p>This is a message for you.</p>
}

<button @onclick="HandleClick">Click me</button>

@code {
    private string Name = "John";
    private bool ShowMessage = true;

    private void HandleClick()
    {
        ShowMessage = !ShowMessage;
    }
}

当Razor引擎解析这个.razor文件时,它会根据一定的规则将其中的HTML代码和C#代码分别解析并转换成相应的C#类代码。下面是大致的生成文件:

代码语言:C#复制
using Microsoft.AspNetCore.Components;

namespace MyNamespace
{
    public class MyComponent : ComponentBase
    {
        private string Name = "John";
        private bool ShowMessage = true;

        protected override void BuildRenderTree(RenderTreeBuilder builder)
        {
            base.BuildRenderTree(builder);

            builder.OpenElement(0, "h1");
            builder.AddContent(1, "Welcome, ");
            builder.AddContent(2, Name);
            builder.CloseElement();

            if (ShowMessage)
            {
                builder.OpenElement(3, "p");
                builder.AddContent(4, "This is a message for you.");
                builder.CloseElement();
            }

            builder.OpenElement(5, "button");
            builder.AddAttribute(6, "onclick", EventCallback.Factory.Create(this, HandleClick));
            builder.AddContent(7, "Click me");
            builder.CloseElement();
        }

        private void HandleClick()
        {
            ShowMessage = !ShowMessage;
            StateHasChanged();
        }
    }
}

在这个生成的C#类代码中:

BuildRenderTree 方法用于构建组件的渲染树,它会按照Razor文件中的结构生成对应的HTML元素和属性。

Razor文件中的静态HTML内容会被转换成 builder.OpenElement 和 builder.CloseElement 方法的调用,用于创建和关闭HTML元素。

Razor文件中的动态内容和事件处理逻辑会被转换成相应的C#代码,用于在运行时执行和处理。

综上,Razor引擎解析.razor或.cshtml文件的原理就是将其中的HTML代码和C#代码分别解析,并根据一定的规则生成相应的C#类代码,以实现页面的动态渲染和逻辑处理。

2.3 blazor框架的前后端交互流程分析

如3.2节所述 .razor文件被解析成 MyComponent类,在blazor server模式处理web请求,实际上发送给浏览器的html实际是静态页面,这个页面的内容由 服务器 执行BuildRenderTree函数生成的。从代码的角度大致简化工作流程如下:

  1. 客户端请求页面: 客户端(浏览器)发送请求到服务器,请求Blazor应用程序的页面。
  2. 服务器处理请求: 服务器接收到请求后,会执行相应的处理逻辑。在Blazor Server模式下,服务器会实例化Blazor组件,并调用其BuildRenderTree方法来生成HTML内容。
  3. 生成HTML内容: 在BuildRenderTree方法中,组件会创建一个渲染树(Render Tree),这个渲染树描述了页面的结构和内容。组件会使用RenderTreeBuilder对象来构建渲染树,向其中添加HTML元素、属性和事件处理逻辑等。
  4. 将HTML发送给客户端: 服务器将生成的HTML内容作为响应发送给客户端(浏览器),浏览器将其解析并渲染到页面上。
  5. 与用户交互: 用户在浏览器中与页面进行交互,例如点击按钮、输入文本等操作。
  6. 处理用户事件: 当用户与页面交互时,浏览器会将相应的事件(如点击事件、输入事件)发送回服务器。
  7. 更新页面内容: 服务器接收到用户事件后,会重新执行相应的处理逻辑,并根据新的状态重新生成HTML内容。然后将更新后的HTML内容发送给客户端,客户端会更新页面上相应的部分而不是整个页面。
  8. 持续通信: 这样的过程会持续进行,服务器和客户端之间通过SignalR进行实时通信,以保持页面内容的同步更新。

3.总结:

  1. Razor引擎的编译过程是将Razor标记页文件中的HTML和C#代码转换成可执行的C#类代码,从而实现了页面逻辑与呈现的分离,同时保留了编写页面逻辑的便利性。
  2. Blazor Server模式下的工作流程是在服务器端生成HTML内容,并将其发送给客户端,以实现动态的页面渲染和交互。客户端与服务器之间通过SignalR进行实时通信,以保持页面的同步更新。

0 人点赞