将服务器端 Blazor 添加到现有 MVC Core 应用程序
Posted
技术标签:
【中文标题】将服务器端 Blazor 添加到现有 MVC Core 应用程序【英文标题】:Adding Server-Side Blazor to an existing MVC Core app 【发布时间】:2019-10-08 00:22:25 【问题描述】:我有一个完全运行的 Blazor 服务器端项目和一个 .NET Core 3 MVC 项目,它们都在同一个解决方案中。我现在尝试在我的 MVC 项目中使用 Blazor 项目中的组件。
我已经设法让组件在 MVC 页面上呈现,但是 Blazor 组件上的按钮单击不会触发组件的 onclick 事件,而是导航到 https://localhost:44341/?
我不清楚我需要在 MVC 解决方案中进行哪些更改才能使其正常工作?官方文档talks about using components in and MVC project,在这个video chat with 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 模板(客户端、客户端托管和服务器端)中启动新项目以寻找线索,但所有这些示例都设置为完整的 SPA托管在 .html 文件中的单个 Blazor 入口点(App
文件),而我想在许多不同的现有 MVC 页面上呈现 Blazor 组件。
然后,我尝试将这些项目的一部分(以及我正在工作的 Blazor 项目的一部分)添加到 MVC 项目中,但无法使其充分发挥作用。
我也尝试关注the answer here,但这是将 Blazor 组件文件添加到 MVC 项目中,而我的 Blazor 文件目前(大部分)位于不同的项目中。
迄今为止我的实验中的随机问题
我在 MVC 应用的 Startup.cs 中添加了services.AddServerSideBlazor();
。那里还需要什么吗?
我的 MVC 应用程序仍在传统的AspNetCore.Routing
上,如果我只将组件放置在现有 MVC 页面上(即我不会有 Blazor 页面,只有 Blazor 组件),我是否还需要切换到 Core 3 的端点路由)。
在浏览器中运行的 blazor javascript 文件(通过 SignalR)与之通信的 Blazor 的服务器端部分是否需要端点路由?我在浏览器中从 js 文件中得到 404。
如果我只是托管组件,是否还需要“App”(App.razor) 类/页面作为入口点?
如果是这样,我是否需要将 _Host.cshtml 中的 <app>@(await Html.RenderComponentAsync<App>())</app>
行放在我的 MVC 项目中的某个位置?
是否需要在我的 MVC 项目中重现 Blazor 项目中的 Pages 和 Shared 文件夹,以及两个 _Imports.razor 文件和 MainLayout.razor 文件?
我认为 Blazor 现在是 Microsoft.NETCore.Platforms 文件的一部分(在 MVC 项目的 SDK 节点下引用),所以我认为我不需要为 Blazor 添加单独的 NuGet 包到 MVC 是否正确项目?
【问题讨论】:
【参考方案1】:我现在已经深究了。在我的问题中描述的所有试验和错误之后,解决方案结果证明只涉及很少的代码。
在同一解决方案中的不同项目中使用服务器端 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 文件的更改
将基本网址添加到头部:
<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 中的已知路由问题
上述更改是我需要进行的所有更改才能使其正常工作。有一个known issue with Core 5,一旦您导航到带有 Blazor 组件的 MVC 或 Razor 页面,在页面刷新之前路由将不再起作用 - 浏览器地址栏中的 URL 将更改,但不会发生导航.
我现在在 Preview 6 上运行,我可以确认路由问题现在已从 Preview 6 开始修复。
在同一项目中使用服务器端 Blazor 和 MVC 的示例
Chris Sainty 有一个将服务器端 Blazor 组件添加到现有 MVC 项目的示例:Using Blazor Components In An Existing MVC Application (source here)
【讨论】:
我一直试图让它在 IIS 中工作,但它试图针对 localhost 而不是应用程序端点运行 javascript。有人知道如何解决这个问题吗? @Paul 你最好提出一个新问题并参考这个答案,而不是在这里的 cmets 中提问。这个问题没有获得大量的浏览量,所以如果您提出一个全新的问题,您将有更好的机会获得答案。 @Paul,另一种想法是,确保浏览器上存在 Blazor.server.js 文件。在 Chrome 中使用 F12 并检查该文件是否存在,并且控制台中没有关于它丢失的任何错误。通常,如果按钮单击等不起作用,那是因为缺少 Blazor.server.js。见***.com/questions/58088302/… 您好,感谢您的帮助。我确实提出了一个新问题,解决方案是将基本 url 标签添加到布局的头部。它在 mvc 模板中丢失。 是的,就是这样。谢谢以上是关于将服务器端 Blazor 添加到现有 MVC Core 应用程序的主要内容,如果未能解决你的问题,请参考以下文章
有没有办法在不覆盖现有类名的情况下将类名添加到 blazor 组件?
如何通过 IdentityServer4 将 OpenId Connect 添加到 ASP.NET Core 服务器端 Blazor Web 应用程序?
如何向服务器端 Blazor 项目添加控制器(而非视图)支持