ASP.NET Core Hosted和Server-Side Blazor有什么真正的区别?

116

我仍在努力理解ASP.NET Core HostedServer-side Blazor之间的区别。我知道已经有相同的问题存在,但是这并不令人满意。实际上,我无处找到令人满意的答案 - 答案或多或少都是一样的。

如果hosted选项使用服务器(IIS,Kestrel),那么为什么是server-side?很令人困惑...官方文档没有解释清楚...

更新

混淆源于我们有三种选项来创建Blazor应用程序。执行dotnew new --list后,我获得:

  1. dotnet new blazorserver(Blazor Server App)

  2. dotnet blazorwasm(Blazor WebAssembly App)

然而,还有第三个选项:

  1. dotnet blazorwasm --hosted(或dotnet blazor --hosted

这与在创建应用程序时在Visual Studio中的复选框相同:

IMG1

文档说:

您可以选择通过选择ASP.NET Core托管复选框来将应用程序配置为使用ASP.NET Core后端

但是没有解释这意味着什么...


17
如果你注意到了,我已经指出了那个问题,但实际上并没有答案 - 这就是为什么我再次提问的原因。 - JohnyL
1
@JohnB 这个问题是:如果两个选项都使用服务器,为什么会有两个选项呢? - JohnyL
2
但我同意 - 命名真的很令人困惑,就在你习惯了某些东西后,他们又改变了它! :-) - jazb
2
@Thangadurai - 这不是一个插件,所以与SL不同。 - jazb
1
@JohnB 你说得没错))) 但实际上我们有三个选项:blazorwasm、blazor hosted 和 blazor server-side!这真的很令人困惑! :) - JohnyL
显示剩余5条评论
6个回答

127

关于您问题的这部分:

然而,还有第三个选项:

  1. dotnet blazorwasm --hosted(或dotnet blazor --hosted

这与在创建应用程序时 Visual Studio 中的复选框相同:

IMG1

文档说:

您可以选择通过选中 ASP.NET Core 托管复选框来配置应用程序以使用 ASP.NET Core 后端

但没有解释它意味着什么...

简短版

'托管'是用于希望站点的后端和使用该后端的 Blazor 客户端都在同一个网站上托管的情况。

详细版

我同意,文档对所有这些并不是非常清楚,但解释实际上比它看起来要简单:

Blazor 应用程序必须在某处“托管”

首先要记住的是,Blazor WebAssembly 'app' 不是一个独立的网站,它是嵌入在网站中的应用程序。在许多情况下,它将像网站一样运行,因为它将用作单页应用程序,但这绝不是必需的。

基本上,Blazor WebAssembly 应用程序是通过编译/发布 Blazor 项目创建的一系列文件和 JavaScript 文件。

然后需要将这些文件放在某个网站上,并且您网站中的 div 标签名称与为您的站点生成的 Blazor JS 文件的组合处理将您的应用文件连接到浏览器的 WebAssembly 部分,以便然后在页面上呈现。

关键在于托管您的 Blazor 应用程序的网站不必是 ASP.NET Core 网站它可以是任何站点,纯 HTML、Drupal 或其他任何站点,只需在正确处理 WebAssembly 和 JavaScript 的浏览器上显示即可。

但是,如果您还在 ASP.NET Core 中编写站点的后端,则可以重用该站点

因此,您的 Blazor 项目不必托管在一个由 ASP.NET Core 编写的网站中,但它确实必须在某个地方进行托管(以便用户可以看到它)。

如果您同时编写站点的后端,例如如果您正在编写 API 或 SignalR hub 以从 Blazor 客户端发送和接收数据,并且如果您正在 ASP.NET Core 中编写该后端,则可以重用同一站点来托管您的 Blazor 客户端。

这种情况下需要使用“托管”选项。
如果您使用上面截图中的模板创建项目,并勾选“托管”选项,您会发现创建的[YourProjectName].Server项目是启动项目,但运行该项目时显示的index.html页面来自[YourProjectName].Client项目。
这种方法意味着您的服务器上只有一个站点(这可能是好事或坏事),并且也意味着您不会遇到任何CORS问题
但您实际上不必拥有ASP.NET Core站点。
如果您的Blazor站点是独立站点,不从任何服务器读写数据,或者仅与第三方API或运行在旧.NET Framework上的现有Web API通信,则根本不需要ASP.NET Core站点。
在那种情况下,您不使用“托管”选项。
相反,您可以简单地发布Blazor项目,然后获取发布文件夹中的文件,并将它们托管在任何站点中。

6
@BlazingNoob,cshtml页面实际上就是Razor页面,而不是Blazor组件。如果你查看Startup.cs文件中的“Configure”方法,你会发现服务器应用程序配置为同时使用Razor页面和Blazor。Blazor和Razor共享站点的路由,所以当你导航到站点的根目录时,你将进入一个Blazor页面。然而,如果在到达该页面之前出现错误,你将被带到Error.cshtml(即“主机”站点的“外层”容器)的错误页面。_Layout.chstml页面是共享布局页面,只是被Error页面使用。 - tomRedox
3
@BlazingNoob,你说得完全正确。为了让事情更加混乱,在MVC端实际上有两种使用.cshtml后缀的由服务器提供的页面:MVC页面和Razor Pages。Razor Pages是一个轻量级的MVC页面版本,不需要独立的控制器来提供服务。这就是为什么没有控制器端点提供错误页面的原因。当他们决定将Blazor组件称为“Razor Components”而不是“Blazor Components”时,这使情况变得非常混乱。我仍然希望他们会改变主意。 - tomRedox
1
@clarkbrent 这是一个Web API项目。添加Blazor服务器端到MVC站点需要单独的命令。 - tomRedox
1
@Tarta 关于这段代码"If our Blazor App was still relying on the server for all the computation then it would be exactly the same as the Blazor Server model"。这不是完全正确的,在Blazor Server中,代码运行在服务器上,因此您不需要rest API,例如可以直接访问EF(但在Blazor WASM中无法工作)。Blazor Server更像WinForms应用程序,因为它的行为类似于TS/RDP会话,其中用户输入被传递到服务器,然后所有工作都在服务器上完成,最后将UI的更改传回客户端。 - tomRedox
1
@Tarta 我还没有在 Blazor 中体验过 CORS 的乐趣,所以说实话我不知道。到目前为止,我们所有的东西都是调用自己的 API。我认为一定有办法做到这一点,因为这是一个非常标准的用例。 - tomRedox
显示剩余16条评论

26

更新

我现在理解你的意思了。混淆源于当您使用客户端托管的Blazor时,有一个名为--hosted的选项。此选项意味着让Blazor包含ASP.NET Core运行时。

为什么需要这个选项?因为您可以编写离线应用程序(例如计算器应用程序),它不需要任何与外部服务的连接,从而使ASP.NET Core无关紧要。但是,您可能希望编写一个在线应用程序,该应用程序可以访问在线数据库、外部API、执行验证等。对于这些类型的应用程序,您需要一个ASP.NET Core堆栈来支持您的应用程序。

请查看此FAQ:https://github.com/aspnet/Blazor/wiki/FAQ#q-can-i-use-blazor-with-aspnet-core-on-the-server

原始回答

它们是两种托管模型:服务器托管和客户端托管。

区别在于应用程序是在服务器还是在客户端托管。服务器托管意味着应用程序逻辑在服务器上运行(您可以将其视为Web Forms),单击按钮会发出 "Ajax "调用请求,服务器接收请求并返回更新后的页面。然而,在这里它使用SignalR而不是 Ajax,这是一种低级别的套接字通信(效率高),并且只更新相关部分而不是整个页面(因此它是单页应用程序)。

另一方面,客户端托管意味着您的逻辑在浏览器内运行。将C#逻辑转换为JS,并嵌入到页面中。因此,逻辑在浏览器中运行。这是WebAssembly引入后才可能的,请参阅相关文档了解更多信息。

假设您要创建一个计算器应用程序。您的服务器托管应用程序将需要与服务器通信以进行每次计算并获取结果,而客户端托管则不需要,并在浏览器中计算结果。

您可能会想知道,为什么我们有两个选项。原因是WebAssembly的支持(客户端托管应用程序依赖于此)在许多浏览器中要么不完整,要么不存在,并且性能也有很大差异。

https://caniuse.com/#feat=wasm


所以:1)blazor:所有的HTML渲染和应用逻辑都仅在浏览器中执行;2)hosted:浏览器仅呈现HTML,但所有逻辑都在服务器上执行(并通过SignalR进行交互);3)server-side:**???** - JohnyL
@JohnyL 只有两个版本:客户端托管(代码在浏览器中运行)或服务器托管(代码在服务器上运行)。 - Ghasan غسان
我已经更新了问题并展示了这三个选项。 - JohnyL
@JohnyL 我现在明白你的意思了。我已经更新了答案。 - Ghasan غسان
1
感谢您澄清更新!现在这个难题已经解决了!谢谢! - JohnyL
14
因为回答的第一部分与问题无关,第二部分也没有恰当地解释当使用“--hosted”选项时Blazor应用程序在浏览器中的服务方式的区别,所以被踩了。 - Craig Brown

18
这个问题涉及到Visual Studio中创建新的Blazor WebAssembly应用时,"ASP.NET Core Hosted"选项的选择。
选择此选项会为您生成3个项目(如果不选择此选项,则只生成1个WebAssembly项目):
1. 服务器端Blazor项目 2. 客户端端Blazor项目(WebAssembly) 3. 共享实体的共享项目,用于服务器和客户端项目之间的共享。
通过此选项,您可以拥有:
1. 仅在浏览器中执行逻辑的Blazor WebAssembly选项。 2. 在服务器上进行所有处理并仅将HTML呈现到浏览器的服务器托管选项。
部署时,所有这些项目都放置在同一个位置。因此,如果您需要同时使用服务器端和客户端端选项,则可以选择该选项。

enter image description here


1
谢谢你的又一篇好回答!因为努力加上1分! - JohnyL

10

在阅读文档时,我也有同样的困惑。但在Blazor WebAssembly部分进行了解释。

dotnet blazorwasm - 是一个独立的项目

dotnet blazorwasm --hosted (或 dotnet blazor --hosted) - 是一个托管了 ASP.NET Core 支持 API 的项目。

托管部署会通过一个运行在 Web 服务器上的 ASP.NET Core 应用程序向浏览器提供 Blazor WebAssembly 应用程序。

客户端的 Blazor WebAssembly 应用程序与服务器应用程序的任何其他静态 Web 资源一起发布到服务器应用程序的 /bin/Release/{TARGET FRAMEWORK}/publish/wwwroot 文件夹中。这两个应用程序一起部署。需要能够托管 ASP.NET Core 应用程序的 Web 服务器。对于托管部署,Visual Studio 包含了 Blazor WebAssembly 应用程序项目模板(使用 dotnet new 命令时为 blazorwasm 模板,并选择 Hosted 选项 (-ho | --hosted))。


9
这是我的意见。
选择带有ASP.NET Core托管的Blazor WebAssembly应用程序复选框创建应用程序。

Blazor Web Assembly app with Asp.net core hosted

一旦创建,观察项目引用。

Blazor WebAssembly App with Asp.Net Core Hosted selected project structure

请注意,服务器项目引用客户端项目。 我和其他人一样也有同样的困惑,即客户端调用服务器,它们是两个独立的Visual Studio项目。因此,这个项目的引用让我感到困惑。
事实上,客户端项目由服务器项目托管和提供服务。当我们想要运行应用程序时,需要运行服务器项目而不是客户端项目。
因此,当您想要运行解决方案(应用程序)时,必须确保将服务器项目设置为启动项目,而不是同时设置服务器和客户端。由于我的最初误解,我设置了多个启动项目,认为客户端(类似React应用程序)调用服务器(WebApi),并且它们都应该同时运行,以便客户端调用服务器。

The server project set as startup project

上面是正确的,但下面是错误的。

Setting both client and server as startup projects.

如果您这样做,您会遇到以下错误,这让我很痛苦。
Microsoft Visual Studio - 发生一个或多个错误。无法启动调试适配器错误。

Failed to launch debug adapter error from Visual Studio

最后,如果您想通过添加不同种类的Blazor应用程序的Docker文件和docker-compose文件来进行Dockarize,请查看此github repo

特别是针对我们正在讨论的这种类型的应用程序,请查看该存储库中的thisthis folder


能否在服务器上路由到页面? - Ranj
1
这是一个很好的答案。在启动文件中,有一个用于启动客户端的定义吗?我的意思是,它需要在某个地方进行配置,以确定应该启动哪个客户端。 - ElConrado
几个问题:Q1. 托管模型中的服务器是否等同于不与Blazor WASM客户端进行SignalR连接的.NET Core API? Q2. 与在服务器上运行的.NET Core API(通过例如Azure App Service进行托管)和在客户端上运行的Blazor WASM(通过例如静态网站进行托管)相比,它是否提供任何好处? 如果可能,请在您的答案中详细说明这些问题。 - Ash K

6

Blazor-WASM

这种应用程序可以在第一次加载后离线工作。 例如,如果您使用Blazor WASM创建贷款计算器,则可以在第一次加载时将所有数据、业务逻辑和验证发送到客户端,例如贷款类型、利率、最大还款期限等。然后由于逻辑也在客户端中,当更改贷款类型或还款期限时,它不需要与服务器进行反复通信,因为客户端中的业务逻辑使用用户选择的数据,Blazor可以呈现UI并显示结果。

Blazor-server

此应用程序使用服务器来呈现UI,因此,在贷款应用程序上,如果用户更改贷款类型,blazor会使用SignalR将该用户更改值发送到服务器,服务器具有获取结果的数据和逻辑,然后服务器呈现UI并使用SignalR将UI更改发送到客户端,并在客户屏幕上重新绘制UI。

Blazor-ASP.NET Core Hosted

Visual Studio在核心托管模板中生成3个项目:

  • ClientProject - 这是一个Blazor-WASM应用程序
  • ServerProject - 这是一个.NET CORE API
  • SharedClassProject - 这是一个类库,保存在客户端和服务器之间共享的对象

就像贷款示例中在第一次加载时会加载贷款类型和计算逻辑到客户端。

如果用户选择了贷款类型,Blazor就会创建一个HTTP调用到API应用程序,以根据所选的贷款类型获取贷款利率(如果该利率在数据库中存在)。

然后用户输入还款期限,由于计算逻辑在客户端中,现在该应用程序可以计算结果并呈现UI来显示结果。因此,使用这种模型,您可以将一些数据或逻辑放在服务器上,将其他数据或逻辑放在客户端上。


2
服务器项目是Web API - 哈哈,但愿他们称之为Blazor Server应用程序! - niico

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接