简体   繁体   English

将 Blazor WASM 作为 Blazor 服务器端运行

[英]Run Blazor WASM as Blazor Server-Side

Problem问题

Blazor WASM could've been easily preferred over Blazor Server-Side without its downsides development-wise. Blazor WASM 可以很容易地比 Blazor 服务器端更受青睐,而且在开发方面没有缺点。 Currently, Blazor WASM doesn't support a full-featured debugging experience and has a very slow startup.目前,Blazor WASM 不支持功能齐全的调试体验,并且启动速度非常慢。 This slows down development much more than with Blazor Server-Side.与 Blazor 服务器端相比,这会大大减慢开发速度。 Though I honestly personally think that the debugging experience slows down the development much more than the slow startup.虽然老实说,我个人认为调试体验比缓慢启动更能减慢开发速度。

Proposed Solution建议的解决方案

NOTE: I included the "proposed" word in there because I'm not sure about the downsides that this solution can cause, so feel free to comment on my answer below.注意:我在其中包含了“建议”一词,因为我不确定此解决方案可能导致的缺点,因此请随时对我的答案发表评论。

The solution is to simply create an additional Blazor Server-Side project then reference the Blazor WASM project to the Blazor Server-Side project.解决方案是简单地创建一个额外的 Blazor 服务器端项目,然后将 Blazor WASM 项目引用到 Blazor 服务器端项目。 Afterwards, add some tweaks to the Startup and the _Host.cshtml of the Blazor Server-Side to properly use the Blazor WASM razor files and the wwwroot files.然后,对 Blazor 服务器端的Startup_Host.cshtml添加一些调整,以正确使用 Blazor WASM razor 文件和 wwwroot 文件。 See my proposed answer below for a step-by-step explanation for this solution.有关此解决方案的分步说明,请参阅下面我提出的答案。

In simpler terms, this solution just adds and configures the Blazor Server-Side project without making any changes and any significant code duplication to the Blazor WASM project.简单来说,此解决方案只是添加和配置 Blazor 服务器端项目,而不会对 Blazor WASM 项目进行任何更改任何重要的代码重复

NOTE: In this example, I'm using Visual Studio 2019 16.7.2 and the version of the templates are currently at 3.1.8注意:在本例中,我使用的是Visual Studio 2019 16.7.2 ,模板版本目前为3.1.8

  1. Create a Blazor WASM project.创建 Blazor WASM 项目。 Either the ASP.NET Core Hosted or the Standalone option will work fine but they will have different configurations later that will be discussed. ASP.NET Core Hosted 或 Standalone 选项都可以正常工作,但稍后将讨论它们将具有不同的配置。 The rest of the options won't have any effect.其余选项不会有任何影响。 In this example, I'll go with the ASP.NET Core Hosted to explain later about having API Controllers.在此示例中,我将使用ASP.NET Core Hosted来解释稍后有关具有 API 控制器的信息。 Also create the Blazor Server-Side project afterwards.之后还要创建 Blazor 服务器端项目。

    创建 ASP.NET Core 托管 Blazor WASM 项目创建 Blazor 服务器端项目


  1. As of this moment, your project structure should be similar to the first screenshot below.到目前为止,您的项目结构应该类似于下面的第一个屏幕截图。

    Delete the highlighted items in the Blazor Server-Side project shown in the second screenshot below.删除下面第二个屏幕截图中显示的 Blazor 服务器端项目中突出显示的项目。

    在此处输入图片说明要从 Blazor 服务器端项目中删除的项目


  1. Reference the Blazor WASM project to the Blazor Server-Side project.将 Blazor WASM 项目引用到 Blazor 服务器端项目。

    • ASP.NET Core Hosted - Reference both the BlazorWasm.Client & BlazorWasm.Server project. ASP.NET Core Hosted - 参考BlazorWasm.ClientBlazorWasm.Server项目。
    • Standalone - Reference the single Blazor WASM project as is.独立- 按原样引用单个 Blazor WASM 项目。

  1. Go to the Startup class of the Blazor Server-Side project.转到 Blazor 服务器端项目的Startup类。 In the ConfigureServices() , remove the WeatherForecastService together with the BlazorServer.Data namespace then add a service for the HttpClient to be used by the razor files from the Blazor WASM project.ConfigureServices() ,删除WeatherForecastServiceBlazorServer.Data命名空间,然后为HttpClient添加一个服务,以供 Blazor WASM 项目中的 razor 文件使用。

     services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(sp.GetRequiredService<NavigationManager>().BaseUri) });

    NOTE In production, I don't suggest creating an instance of the HttpClient .注意在生产中,我不建议创建HttpClient的实例。 Use the IHttpClientFactory instead.请改用IHttpClientFactory Visit this article Use IHttpClientFactory to implement resilient HTTP requests .访问这篇文章使用 IHttpClientFactory 实现弹性 HTTP 请求

    For ASP.NET Core WASM Projects对于 ASP.NET Core WASM 项目

    In the Configure() , map the controllers' endpoints.Configure() ,映射控制器的端点。 This will use the controllers in the X.Server / BlazorWasm.Server project.这将使用X.Server / BlazorWasm.Server项目中的控制器。

     app.UseEndpoints(endpoints => { endpoints.MapControllers(); ... });

  1. Go to the _Host.cshtml in the /Pages folder of the Blazor Server-Side project.转至_Host.cshtml在Blazor服务器端项目/ Pages文件夹。 Change the reference of the css/site.css to css/app.css since the filenames for the main css file for the Blazor WASM project are different.css/site.css的引用更改为css/app.css因为 Blazor WASM 项目的主 css 文件的文件名不同。

     <link href="css/site.css" rel="stylesheet" /> <!-- Previous --> <link href="css/app.css" rel="stylesheet" /> <!-- New -->

  1. Lastly, change the App in the type attribute of the component tag and refer to the App razor class file in the Blazor WASM project.最后,在component标签的type属性中更改App并参考 Blazor WASM 项目中的App razor 类文件。 In this example, the App class is found in the BlazorWasm.Client project:在此示例中, App类位于BlazorWasm.Client项目中:

     <component type="typeof(App)" render-mode="ServerPrerendered" /> <!-- Previous --> <component type="typeof(BlazorWasm.Client.App)" render-mode="ServerPrerendered" /> <!-- New -->

That's it!就是这样! When you run the Blazor Server-Side project, it should load without the "Loading ..." text.当你运行 Blazor 服务器端项目时,它应该在没有“正在加载...”文本的情况下加载。

  • No changes made to the Blazor WASM project(s) and no significant code duplication made.没有对 Blazor WASM 项目进行任何更改,也没有进行重大的代码重复。
  • The only things to change are the references and the launchSettings.json & appsettings.json .唯一需要更改的是引用和launchSettings.jsonappsettings.json
  • As for the configurations in the Startup for the Blazor Server-Side, you can just create extension methods in the Blazor WASM project(s) and use them in the Blazor Server-Side project.至于 Blazor 服务器端Startup的配置,您只需在 Blazor WASM 项目中创建扩展方法并在 Blazor 服务器端项目中使用它们即可。

NOTE: I honestly think this is ideally(?) only for debugging during development since the WASM razor files won't fully utilize the capability of a true Blazor Server-Side because it would still use HTTP Requests.注意:老实说,我认为这理想情况下(?)仅用于开发期间的调试,因为 WASM razor 文件不会完全利用真正的 Blazor 服务器端的功能,因为它仍然会使用 HTTP 请求。

作为 Blazor 服务器端运行的 Blazor WASM 项目


Hoping for feedbacks down below!希望楼下多多指教! :DD :DD

I would suggest an alternate way.我会建议另一种方式。 There are other drawbacks to referring to WASM project from a server project, but personally I think it is an architecturally inelegant solution.从服务器项目中引用 WASM 项目还有其他缺点,但我个人认为这是一种架构上不优雅的解决方案。

There are some critical areas where Blazor Server and WASM differ : Blazor Server 和 WASM 在一些关键领域有所不同:

  1. Authentication: Blazor server allows you to customize access to specific areas at runtime.身份验证:Blazor 服务器允许您在运行时自定义对特定区域的访问。 In WASM, the authorization happens in one go and the app code is sent in its entirety.在 WASM 中,授权是一次性完成的,应用程序代码是完整发送的。
  2. Database is access : Blazor server allows direct access to EF core entities (since the code executes only on the server).数据库访问:Blazor 服务器允许直接访问 EF 核心实体(因为代码仅在服务器上执行)。 In blazor, it is realistically not possible to access any database directly.在 blazor 中,实际上不可能直接访问任何数据库。 It is also highly discouraged because you would be sending connection strings to the client.也非常不鼓励这样做,因为您将向客户端发送连接字符串。 Hence you need to write a separate web API for data access.因此,您需要为数据访问编写一个单独的 Web API。 3.Settings files : you can have as many settings files in server-side blazor. 3.设置文件:您可以在服务器端blazor中拥有尽可能多的设置文件。 Client side blazor loads only appsettings.json by default.默认情况下,客户端 blazor 仅加载 appsettings.json。 A special mechanism is required to include multiple .json files.需要一种特殊的机制来包含多个 .json 文件。

Therefore, for most applications (and definitely the ones that require database access) you will not be able to share 100% codebase between WASM and Server-side.因此,对于大多数应用程序(绝对是需要访问数据库的应用程序),您将无法在 WASM 和服务器端之间共享 100% 的代码库。

Here is what you should do instead:这是你应该做的:

  1. For the points mentioned above, (auth, but mostly db access), create a data access service dependency (say IDataAccessLayer).对于上面提到的要点(身份验证,但主要是数据库访问),创建数据访问服务依赖项(比如 IDataAccessLayer)。 One implementation will access the database directly (to be used in server side) The other implementation will access the database through an HttpClient (to be used in blazor WASM).一种实现将直接访问数据库(用于服务器端)另一种实现将通过 HttpClient 访问数据库(用于 blazor WASM)。

  2. Now, put your entire app in an RCL.现在,将您的整个应用程序放在一个 RCL 中。 Call it "BlazorAppRCL".称之为“BlazorAppRCL”。 This RCL obviously does not have Startup.cs and Program.cs这个 RCL 显然没有 Startup.cs 和 Program.cs

  3. Create a project for server and client specific db access implementation为服务器和客户端特定的数据库访问实现创建一个项目

  4. Now, you have the following set of projects:现在,您拥有以下一组项目:

For Server Side: BlazorServer (has only settings + Program.cs + Startup.cs).对于服务器端:BlazorServer(只有设置 + Program.cs + Startup.cs)。 It refers to the RCL + Server specific implementation of IDataAccessLayer它是指 IDataAccessLayer 的 RCL + Server 特定实现

For hosted WASM: BlazorWebAPI : For database access, it has API to access database BlazorClientDAL : WASM specific implementation of IDataAccessLayer BlazorWASM : Blazor WASM project All three refer to your BlazorAppRCL.对于托管 WASM: BlazorWebAPI :对于数据库访问,它具有访问数据库的 API BlazorClientDAL :IDataAccessLayer 的 WASM 特定实现 BlazorWASM :Blazor WASM 项目这三个都是指您的 BlazorAppRCL。

The crux is to use DI/ inversion of control pattern to address the divergence between WASM and Server.关键是使用 DI/控制反转模式来解决 WASM 和 Server 之间的分歧。 This way, you can have a both instances WASM and Server instances with minimal code divergence.通过这种方式,您可以同时拥有 WASM 实例和服务器实例,并且代码差异最小。 Note that the WASM WebAPI can simply use the server side blazor's implementation od IDataAccessLayer as it is.请注意,WASM WebAPI 可以直接使用服务器端 blazor 的 IDataAccessLayer 实现。 So beyond API related overhead, additional coding is not necessary.因此,除了 API 相关的开销之外,不需要额外的编码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM