【问题标题】:How to host Blazon in Razor Pages application如何在 Razor Pages 应用程序中托管 Blazon
【发布时间】:2021-05-17 20:37:47
【问题描述】:

“标准”Blazor WASM 应用程序托管在静态 HTML 页面中;例如,index.html。由于某些要求,我想在 Razor 页面应用程序中托管 Blazor。

我所做的是从“标准”Blazor WASM 应用程序开始,删除静态文件,因为我不需要它们,将 index.html 的内容移动到 Wasm.cshtml,并将 endpoints.MapFallbackToFile("index.html"); 更改为 @987654325 @。

一切似乎都按预期进行;我可以运行应用程序并导航到 Blazor 中的不同页面。

但是,当我尝试使用其 URL 访问页面时,事情就崩溃了;例如,http://mysite/counter,其中/counter 是 Blazor 中的一个页面,我收到以下错误:

An unhandled exception occurred while processing the request.
AmbiguousMatchException: The request matched multiple endpoints. Matches:

/Wasm
/Wasm

谁能帮我找出我做错了什么?

附注:

  • 我在这里查看了一些答案,但我发现的只是人们在谈论 Blazor Server。
  • 我正在使用 .NET 3.1 和 Blazor 3.2。
  • 我想使用我的 Razor Pages 应用程序来托管/服务 Blazor WASM,而不是将它们混合在一个项目中。它们仍然是 2 个不同的项目。
  • 我完全知道 Blazor WASM 和 Razor Pages 是不相关的技术。我不是想整合它们。我只是想从动态页面服务器 Blazor WASM 文件。如果它让您更好地思考我想要实现的目标,请将 Razor Pages 视为任何服务器端技术; PHP、Node 或其他任何东西,然后将其应用于我要解决的路由问题。

【问题讨论】:

  • 这将如何运作?哪个平台(Razor Pages 或 Blazor)可以处理路由?
  • 这不是endpoints.MapFallbackToPage("/index") 应该处理的吗?来自文档:[it] 旨在处理请求的 URL 路径不包含文件名且没有其他端点匹配的情况。这便于将动态内容请求路由到 SPA 框架,同时还允许对不存在文件的请求导致 HTTP 404。
  • 如果这是这里发生的唯一事情,我可以理解这一点。但即使我更改 Blazor Index.razor 页面的路由,我也会遇到同样的错误。无论如何,看起来我在这里遗漏了一些东西,这就是我要问的。
  • 目前还不清楚您在这里要完成什么; Razor 和 Blazor 不是竞争框架,它们是相同技术的不同实现。为什么要将一个动态框架放在第二个动态框架中?
  • 简而言之,我有一个现有的 Razor Pages 应用程序,我想将 Blazor 添加到它,因为我想在类似 SPA 的页面中实现它们的某些要求。如果他们不竞争,让他们住在一起有什么问题?我可以在 Razor Pages 应用程序中托管 JavaScript 框架,不是吗? Razor 将处理路由,当它到达 Blazor 页面时,Blazor 将从那里获取它,因为没有任何页面会到达服务器以在路由中发生冲突。我的问题是替换index.html

标签: asp.net-core blazor razor-pages blazor-webassembly


【解决方案1】:

你提供的信息很少,所以我不得不做出一些猜测。

我猜您的 WASM 集成基于 Blazor WASM ASP.NET 托管模板。该模板由三个项目组成:.Client 项目、.Server 项目和一些具有共享模型的额外项目(他们可能正在做干净的架构)。服务器项目是 Razor pages 项目,客户端是 WASM 项目。

您必须了解的是,Blazor WASM 项目无法与 Razor 页面应用程序相提并论。 Blazor WASM,或者实际上任何 WASM 文件是不同类型的二进制文件,并且完全在客户端运行!它是一个客户端应用程序。 IE。输出二进制完全不同。您不能有一个项目同时生成服务器 (x86/arm) 二进制文件和客户端 (WASM) 二进制文件。您需要两个独立的项目。

编译 WASM 项目时实际发生的情况是,所有页面路由也都转换为 WASM。更改页面时只需检查您的网络流量。即使您的浏览器 url 发生变化,那也是 fake... 没有网络流量!事实上,你们保持在同一个页面上。

现在想想当您在浏览器中手动输入“[..]/counter”时会发生什么。主机实际上将再次从根 ("/" = "/Index") 下载相同的 .wasm 文件,然后解析路由客户端。

回到你的问题。出于某种原因,您将 Blazer WASM 项目 wwwroot/index.html 的所有内容复制到了 Razor Page 项目 Pages/Index.cshtml。现在你混淆了整个路由系统。当您键入“[...]/counter”时,WASM 路由器会告诉您需要从“/Index”下载.wasm 文件。同时 Razor Pages 路由器会告诉你编译后的Index.cshtml 可以在“/Index”找到。这会给你的“AmbiguousMatchException:请求匹配多个端点。匹配:/Index /Index”

看看UseBlazorFrameworkFiles的总结就知道了:

将应用程序配置为从根路径“/”提供 Blazor WebAssembly 框架文件。

解决方案只是保持 WASM 项目中的 index.html 原样。只需查看默认的 Blazor WASM ASP.Net 应用程序:它同时托管 Blazor WASM、Razor Pages MVC,并且路由很好。

另一种解决方案是使用UseBlazorFrameworkFiles 的重载,您可以在其中提供路径前缀。例如

app.UseBlazorFrameworkFiles("/wasm");

您需要修复其他路由。

编辑: 那么让我们举一个案例。你有:

  • 为页面//counter 等提供服务的 Blazor WASM 项目。
  • 一个 Razor 页面项目,服务于页面 /weatherforecast 等。

现在:

  1. 您在/ 上启动应用程序。这会从服务器加载 WASM。
  2. 接下来单击计数器图标。 这不会改变页面!:它会显示计数器页面并更新导航 url,但不会加载新页面。
  3. 现在去weatherforecast。这在 WASM 中找不到,因此实际上是从服务器加载了一个新页面。 (剃须刀页面或控制器/视图)
  4. 如果您要返回counter,则在服务器上找不到,因此服务器“回退”到根目录 (/Index) 并再次加载 WASM。接下来看看是否在 WASM 中找到了counter

拥有一个动态的/Index 会破坏这个系统,所以你必须手动解决所有的路由问题。

【讨论】:

  • 重申@JHBonarius 所说的内容,并以稍微不同的方式表达。 Blazor 应用程序启动后,将不再进行 URL 导航。路由真的有点用词不当。 Blazor Routing 意味着获取提交的 URL,通过Router 组件计算出需要将哪些新组件加载到 CURRENT 页面中并加载它。然后不留痕迹地接收导航请求。只有NavigationManager.NavigateTo ("URL", true) 会强制加载新页面(并销毁当前 SPA 实例)。
  • @ShaunCurtis 这仅适用于 Blazor WASM 应用程序。服务器端是另一回事。
  • @ShaunCurtis 我刚刚检查过:Blazor WASM 部分也不完全正确。这仅适用于可以内部路由的页面。如果您路由到应用程序外部的页面(可以是 MVC、Razor 页面、html 等),它仍然是外部路由(使用您所指的“导航”)。
  • @JHBonarius,你的第一个猜测并不准确,除非你的意思是我受到模板的启发。我已经有一个 Razor Pages 应用程序,我将 Blazor WASM 添加到该应用程序中,并且不是从 Blazor WASM 托管模板开始的。我不确定您所说的“不可比较”是什么意思。是的,我完全知道 Razor Pages 和 Blazor WASM 没有关系,彼此没有任何关系。我正在使用 Razor Pages 应用程序来提供二进制文件,我这样做是因为或某些要求,并且因为我已经拥有此应用程序并且没有使用 JavaScript SPA 框架的计划。
  • @JHBonarius,我将检查您提出的一些建议,看看是否适用于我的情况。但是,带回 index.html 不是一种选择,因为删除静态页面是我从 Razor Pages 提供 Blazor WASM 的原因之一。顺便说一句,我昨天在发布此问题后取得了一些进展,现在我没有收到此错误,但与 Blazor WASM 文件的提供位置有关。所以,也许像app.UseBlazorFrameworkFiles("/wasm"); 这样的东西会有所帮助。
【解决方案2】:

好的,根据您目前所写的内容,请查看ShaunCurtis/Blazor-Experimental on Github。这是一些实验性代码的临时回购。忽略 BlazorTest。启动项目是 Blazor-Experimental。

默认页面是普通的剃须刀页面。这是一个混合 Razor、Blazor Server 和 Blazor WASM 站点。所有 WASM 路由看起来都像 wasm/fetchdata,因此我们为所有服务器和 WASM“页面”设置了不同的 URL。

Startup 使用多个端点区分 URL,因此 Blazor WASM 应用程序“范围”内的任何 URL 都设置为 _wasm.cshtml。无法直接映射的任何其他内容都在 Blazor 服务器应用程序的“范围”中,地址为 _host.cshtml。网站上的所有计划 Razor 页面都按原样提供。您根本不需要 Blazor 服务器位,只需回退到默认的 Razor 页面即可。

  endpoints.MapFallbackToPage("/wasm/{**segment}", "/_wasm");
  endpoints.MapFallbackToPage("/_Host");

总结答案:

  • 创建一个 Blazor WASM 项目。您可以从 Blazor 托管模板中复制一个。
  • 从 Razor Pages 项目中引用该项目。
  • 创建将托管 Blazor WASM 的页面;例如Wasm.cshtml,并确保没有设置页面路由;即只有@page在页面顶部,所以它采用默认路由/wasm
  • 将 Blazor WASM 项目中index.html 中的代码复制到Wasm.cshtml
  • 重要提示:如果您使用自己的布局,请务必在页面或布局<head> 部分上添加<base href="/" />
  • 从 Blazor WASM 项目中删除所有静态文件;例如,index.html
  • 从 Blazor WASM 项目中删除所有 *.razor 页面。
  • Wasm.razor 添加到Blazor WASM 项目并将其路由设置为/wasm;即@page "/wasm"
  • 在 Razor Pages 项目的 Startup.cs 中,在 app.UseStaticFiles(); 之后添加 app.UseBlazorFrameworkFiles();
  • 同样在同一个Startup.cs中,在app.UseEndpoints() lambda中添加endpoints.MapFallbackToPage("/wasm/{**segment}", "/wasm");
  • 现在运行应用程序并导航到/wasm。除了您设置的任何布局之外,您还应该看到 Wasm.razor 的内容。粘贴 URL http://whateveryoursiteis/wasm 会得到相同的结果。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2020-05-18
  • 2022-06-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-25
  • 1970-01-01
  • 2014-10-03
相关资源
最近更新 更多