将服务器端 Blazor 添加到现有 MVC 核心应用

Adding Server-Side Blazor to an existing MVC Core app

我有一个完全运行的 Blazor 服务器端项目和一个 .NET Core 3 MVC 项目,它们都在同一个解决方案中。我现在正尝试在我的 MVC 项目中使用 Blazor 项目中的组件。

我已经设法让组件呈现在 MVC 页面上,但是单击 Blazor 组件上的按钮不会触发组件的 onclick 事件,而我只是导航到 https://localhost:44341/

我不清楚我需要在 MVC 解决方案中进行哪些更改才能使其正常工作?官方文档talks about using components in and MVC project and it's mentioned in this video chat with Dan Roth,但都没有详细说明如何实现。

谁能带我了解如何将服务器端 Blazor 改造为 MVC 项目的完整步骤(或举个例子)?

我试过的

我的 Blazor 项目仍然有标准模板的计数器组件,所以我尝试通过引用 Blazor 项目将其添加到我的 MVC 解决方案,然后将其添加到我的 index.cshtml 文件中:

<div id="Counter">
  @(await Html.RenderComponentAsync<Counter>())
</div>

呈现正确但按钮点击不起作用。

我已经将 JS 文件添加到 MVC 应用程序 _Layout 页面:

<script src="_framework/blazor.server.js"></script>

在 MVC 项目的 Startup.cs 文件中打开服务器端 Blazor:

services.AddServerSideBlazor();

我还在 MVC 项目中添加了 Pages 和 Shared 目录,并复制了 _Imports 和 MainLayout 文件 - 不确定是否需要。

当那没有成功时,我尝试从所有 Blazor 模板(客户端、客户端托管和服务器端)启动新项目以寻找线索,但所有这些示例都设置为完整具有单个 Blazor 入口点(App 文件)的 SPA 托管在 .html 文件中,而我想在许多不同的现有 MVC 页面上呈现 Blazor 组件。

然后我尝试将这些项目的一部分(以及我工作的 Blazor 项目的一部分)添加到 MVC 项目中,但无法使其完全运行。

我也尝试遵循 ,但这是将 Blazor 组件文件添加到 MVC 项目中,而我的 Blazor 文件目前(大部分)在不同的项目中。

迄今为止我实验中的随机问题

我现在已经弄清楚了。在我的问题中描述的所有试验和错误之后,解决方案结果涉及的代码少得惊人。

在同一解决方案的不同项目中使用 Server-Side Blazor 和 MVC 的示例

下面的答案假定您的解决方案中有一个正在运行的 server-side Blazor 项目,并且正尝试在同一解决方案的单独 MVC 项目中使用该项目的组件。我在 VS2019 中使用 Core 3 Preview 5 完成了此操作。

请参阅页面底部或 link 同一项目中的 MVC 和 Blazor 示例。

对 MVC 项目的 .csproj 文件的更改

您只需添加对您的 Blazor 项目的引用:

    <ProjectReference Include="..\MyClient.Web.Blazor\MyClient.Web.Blazor.csproj" />

对 MVC 项目的 Views\Shared\_Layout.cshtml 文件的更改

将基数 url 添加到头部:

<head>
<meta charset="utf-8" />
<base href="~/" />

添加对 Blazor JS 脚本的引用

<script src="_framework/blazor.server.js"></script>

(这实际上并不存在于您的本地文件系统中,Blazor 在应用到达浏览器时自动将其整理出来)

对 MVC 项目的更改 Startup.cs

这是完成真正工作的地方

ConfigureServices方法中添加:

services.AddServerSideBlazor();

然后我将我的配置切换到新样式的 Core 3 配置(因此不再使用 AddMvc 方法):

services.AddControllersWithViews()            
    .AddNewtonsoftJson(options =>
    {
        options.SerializerSettings.ContractResolver = new DefaultContractResolver();
    });

services.AddRazorPages();

然后最终使它对我有用的更改是在 Configure(IApplicationBuilder app, IWebHostEnvironment env) 方法中切换到 Core 3 的端点路由:


app.UseRouting();

app.UseEndpoints(endpoints =>
{
    endpoints.MapControllerRoute(
        name: "default",
        pattern: "{controller=Home}/{action=Index}/{id?}");
    endpoints.MapRazorPages();
    endpoints.MapBlazorHub();
});

//app.UseMvc(routes =>
//{
//    routes.MapRoute(
//        name: "MyArea",
//        template: "{area:exists}/{controller=Home}/{action=Index}/{id?}");

//    routes.MapRoute(
//        name: "default",
//        template: "{controller=Home}/{action=Index}/{id?}");
//});

注释掉的代码显示了我使用的旧式路由。我认为是 endpoints.MapBlazorHub(); 的缺失导致了我的按钮点击问题

对 Blazor 项目的更改

无需对 Blazor 项目进行任何更改即可实现此功能。

然后如何将 Blazor 组件放在 MVC 页面上

完成上述所有操作后,让您的组件呈现在 MVC 页面上所需要做的就是添加

 @(await Html.RenderComponentAsync<YourComponent>())

这应该适用于 MVC 页面和 Razor 页面。

Core 3 Preview 5 中的已知路由问题

以上更改是我需要进行的所有更改才能使其正常工作。有一个 ,一旦您导航到上面有 Blazor 组件的 MVC 或 Razor 页面,路由将不再有效,直到页面刷新 - URL 将在浏览器的地址栏中更改,但没有导航会发生。

我现在 运行 使用预览版 6,我可以确认路由问题现在已从预览版 6 开始修复。

Server-Side Blazor 和 MVC 在同一项目中的示例

Chris Sainty 在此处有一个 server-side Blazor 组件添加到现有 MVC 项目 的示例:Using Blazor Components In An Existing MVC Application (source here)