处理 MVC 页面上的静态 Blazor 表单组件

问题描述 投票:0回答:1

理论上,使用静态渲染模式发布 Blazor 表单应该可行。 但是,它不是由 Blazor 处理,而是作为 MVC 表单处理,发布到

/

根据客户的要求,我使用静态渲染模式。

我错过了什么?

  1. 互动性?
  2. Blazor 的
    <Router />
  3. Blazor 的脚本标签?
    <script src="_framework/blazor.web.js"></script>

假设:

  • 不需要交互性。
  • 2 和 3 都有意义,但我们正在进入完整的 SPA 模式,而客户更喜欢逐步演变。

可以通过多种方式在 MVC 页面上呈现 Blazor 组件:

  1. 使用
    RenderComponentAsync
    的示例:
    @(await Html.RenderComponentAsync<SubscribeToNewsletterForm>(RenderMode.Static, new
    {
        BtnLabel = "Subscribe"
    }))
  1. 使用示例:
    <component type="@(typeof(SubscribeToNewsletterForm))" render-mode="Static" />

我已经尝试过:

  • 两种方法都可以,但 Blazor 不处理表单帖子。
  • 添加
    <script src="_framework/blazor.web.js"></script>
    包括
    BlazorFrameworkFiles
    无济于事。

最后,我使用静态渲染模式创建了完整的 Blazor SPA,并将 MVC 移动到不同的路线上运行。

Blazor SPA 正确处理表单,因此我的假设是 Blazor

<Router />
需要干预表单发布和导航。

我的假设正确吗? 如果是这样,在 MVC 页面上使用 Blazor 组件仅限于渲染?

具有以下形式的 Blazor 组件:

<EditForm Model="@SubscriptionModel" OnValidSubmit="@HandleSubscriptionForm" FormName="SubscriptionModel">
    <FluentValidationValidator/>

    <div class="input-group">
        <InputText type="email" class="form-control email-input" required
                   placeholder="Enter your email" aria-label="Enter your email" @bind-Value="SubscriptionModel.Email"/>

        <button class="btn btn-primary subscribe-button" type="submit">@BtnLabel</button>
    </div>

    <ValidationSummary/>
</EditForm>

@code {
    [Parameter]
    public string? BtnLabel { get; set; } = "Join";

    [SupplyParameterFromForm]
    public SubscribeToNewsletterRequest? SubscriptionModel { get; set; }

    protected override void OnInitialized()
    {
        SubscriptionModel ??= new SubscribeToNewsletterRequest();
    }

    private async Task HandleSubscriptionForm()
    {
        Console.WriteLine("Handling subscription form...");
        ...
    }

    public record SubscribeToNewsletterRequest
    {
        public string Email { get; set; }
    }
}
asp.net-mvc model-view-controller blazor blazor-server-side
1个回答
0
投票

您需要非常小心地谈论 Blazor Server 的服务器端渲染,因为组件可能会在两个位置之一渲染。

  1. 静态服务器端渲染 [SSSR] 是在

    HttpRequest
    上下文中渲染组件的位置。除了单例服务之外的所有内容都是在上下文中创建和销毁的。这是经典的老式 MVC、Razor 和 ASP。

  2. 活动服务器端渲染 [ASSR] 是指在 Blazor 中心的集线器会话上下文中渲染浏览器上的 SPA 会话。

由于您提供的代码不是有效的 MRE [最小可重现示例],我将使用 MS 文档中的 Starship 示例代码。请参阅 https://learn.microsoft.com/en-us/aspnet/core/blazor/forms/?view=aspnetcore-8.0

App

中设置路由组件如下
    <Routes />

下面的页面将在 HttpRequest Context 中渲染 ASSR。该表单会将页面发送回服务器,并由

Starship
表单进行处理。在 Id 中输入超过 10 个字母,然后按 Tab 键退出输入,但没有任何反应。没有交互性,因为没有定义。仅当您将表单发送回服务器时才会进行验证。

尝试使

InputText
交互以尝试显示验证消息。你会得到一个错误。
InputText
依赖于
EditForm
的级联参数,而静态渲染
EditForm
时这些参数不存在。它们存在于渲染 EditForm
HttpRequest Context
中。但是
InputText
存在于 Hub 会话上下文中。

@page "/starship"
@using System.ComponentModel.DataAnnotations
@inject ILogger<Starship> Logger

<EditForm Model="@Model" OnValidSubmit="@Submit" FormName="Starship">
    <DataAnnotationsValidator />
    <ValidationSummary />
    <label>
        Identifier:
        <InputText @bind-Value="Model!.Id" />
    </label>
    <button type="submit">Submit</button>
</EditForm>

@code {
    [SupplyParameterFromForm]
    public Starship? Model { get; set; }

    protected override void OnInitialized() => Model ??= new();

    private void Submit()
    {
        Logger.LogInformation("Id = {Id}", Model?.Id);
    }

    public class Starship
    {
        [Required]
        [StringLength(10, ErrorMessage = "Id is too long.")]
        public string? Id { get; set; }
    }
}

为整个表单添加交互性,现在您可以在页面中获得交互性的内容。在表单验证中输入太多字母并按 Tab 键离开触发器,您会立即收到一条验证消息。

@page "/starship"
@using System.ComponentModel.DataAnnotations
@inject ILogger<Starship> Logger
@rendermode InteractiveServer

<EditForm Model="@Model" OnValidSubmit="@Submit" FormName="Starship">

在这种情况下,路由器仍然在 SSSR 模式下运行,因此每个页面都会发送回服务器,最初静态渲染,然后根据页面/组件的渲染设置进行渲染。

如果您设置:

    <Routes @rendermode="InteractiveServer" />

然后你就可以进行全局设置了。这与旧的 Blazor Server 模式相同。路由器不会在 SPA 内呈现,并且不会回发到服务器。

个人评论

如果这是从现有服务器端渲染应用程序的迁移,那么以混合模式运行来进行增量迁移就可以了。如果这是一个新的应用程序,那就没有意义了。您将创造额外的复杂性而没有任何好处。额外的复杂性将会带来巨大的成本。

© www.soinside.com 2019 - 2024. All rights reserved.