14

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

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

我不清楚我需要在 MVC 解决方案中进行哪些更改才能使其正常工作?官方文档讨论了在 MVC 项目中使用组件,并且在与 Dan Roth的视频聊天中提到了它,但都没有详细说明如何实现它。

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

我试过的

我的 Blazor 项目仍然具有标准模板的 Counter 组件,因此我尝试通过引用 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 文件中打开 Server Side Blazor:

services.AddServerSideBlazor();

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

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

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

我也尝试按照此处的答案进行操作,但这适用于将 Blazor 组件文件添加到 MVC 项目中,而我的 Blazor 文件目前(大部分)位于不同的项目中。

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

  • 我已services.AddServerSideBlazor();在 MVC 应用程序的 Startup.cs 中添加。那里还需要什么吗?
  • 我的 MVC 应用程序仍在传统上AspNetCore.Routing,如果我只将组件放置在现有 MVC 页面上(即我不会有 Blazor 页面,只有 Blazor 组件),我是否还需要切换到 Core 3 的端点路由。
  • 在浏览器中运行的 blazor javascript 文件(通过 SignalR)与之通信的 Blazor 的服务器端部分是否需要端点路由?我在浏览器中从 js 文件中得到一个 404。
  • 如果我只是托管组件,我还需要“App”(App.razor)类/页面作为入口点吗?
  • 如果是这样,我是否需要将<app>@(await Html.RenderComponentAsync<App>())</app>_Host.cshtml 中的行放在我的 MVC 项目中的某个位置?
  • 我是否需要从我的 MVC 项目中的 Blazor 项目中重现 Pages 和 Shared 文件夹,以及两个 _Imports.razor 文件和 MainLayout.razor 文件?
  • 我认为 Blazor 现在是 Microsoft.NETCore.Platforms 文件的一部分(在 MVC 项目的 SDK 节点下引用),所以我认为我不需要为 Blazor 添加单独的 NuGet 包到 MVC 项目是否正确?
4

1 回答 1

16

我现在已经深究了。在我的问题中描述的所有试验和错误之后,解决方案结果证明只涉及很少的代码。

同一解决方案中不同项目中的服务器端 Blazor 和 MVC 示例

下面的答案假定您的解决方案中有一个正在工作的服务器端 Blazor 项目,并尝试在同一解决方案中的单独 MVC 项目中使用该项目中的组件。我在 VS2019 中使用 Core 3 Preview 5 进行了此操作。

请参阅页面底部或指向同一项目中 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 中的已知路由问题

上述更改是我需要进行的所有更改才能使其正常工作。Core 5存在一个已知问题,一旦您导航到带有 Blazor 组件的 MVC 或 Razor 页面,在页面刷新之前路由将不再起作用 - 浏览器地址栏中的 URL 将更改,但没有导航会发生。

我现在在 Preview 6 上运行,我可以确认路由问题现在已从 Preview 6 开始修复。

在同一项目中使用服务器端 Blazor 和 MVC 的示例

Chris Sainty 在此处将服务器端 Blazor 组件添加到现有 MVC项目中的示例: 在现有 MVC 应用程序中使用 Blazor 组件来源此处

于 2019-05-21T20:07:36.117 回答