如何在 Razor Pages 应用程序中托管 Blazon
How to host Blazon in Razor Pages application
“标准”Blazor WASM 应用程序托管在静态 HTML 页面内;例如,index.html
。由于某些要求,我想在 Razor 页面应用程序中托管 Blazor。
我所做的是从“标准”Blazor WASM 应用程序开始,删除静态文件,因为我不需要它们,将 index.html
的内容移动到 Wasm.cshtml
,然后更改endpoints.MapFallbackToFile("index.html");
到 endpoints.MapFallbackToPage("/Wasm");
.
一切似乎都在按预期进行;我可以 运行 应用程序并导航到我在 Blazor 中的不同页面。
但是,当我尝试使用 URL 访问页面时,事情就崩溃了;例如,http://mysite/counter
,其中 /counter
是 Blazor 中的一个页面,我收到以下错误:
An unhandled exception occurred while processing the request.
AmbiguousMatchException: The request matched multiple endpoints. Matches:
/Wasm
/Wasm
谁能帮我找出我做错了什么?
P.S.:
- 我在这里查看了一些答案,但我发现的只是人们在谈论 Blazor Server。
- 我正在使用 .NET 3.1 和 Blazor 3.2。
- 我想将我的 Razor Pages 应用程序用于 host/serve Blazor WASM,而不是将它们混合在一个项目中。他们仍然是 2 个不同的项目。
- 我完全知道 Blazor WASM 和 Razor Pages 是不相关的技术。我不是要整合它们。我只是想从动态页面服务器 Blazor WASM 文件。如果它能让您更好地思考我要实现的目标,请将 Razor Pages 视为任何服务器端技术; PHP、Node 或其他任何东西,然后将其应用于我要解决的路由问题。
你提供的信息太少了,所以我不得不做一些猜测。
我猜你的 WASM 集成基于 Blazor WASM ASP.NET 托管模板。该模板由三个项目组成:.Client
项目、.Server
项目和一些具有共享模型的额外项目(他们可能在做清洁架构)。服务器项目是一个 Razor 页面项目,客户端是一个 WASM 项目。
您必须了解的是,Blazor WASM 项目无法与 Razor 页面应用程序相提并论。 Blazor WASM,或者实际上任何 WASM 文件都是一种不同类型的二进制文件,并且在客户端完全运行!它是一个客户端应用程序。 IE。输出二进制文件完全不同。您不能让一个项目同时生成服务器 (x86/arm) 二进制文件和客户端 (WASM) 二进制文件。您需要两个单独的项目。
编译 WASM 项目时实际发生的是,所有页面路由也都转换为 WASM。只需在更改页面时检查网络流量即可。即使您的浏览器 url 发生变化,那也是 假 ... 没有网络流量!事实上,您保持在同一页面上。
现在想一想当您在浏览器中手动输入“[..]/counter”时会发生什么。主机实际上会再次从根目录 ("/" = "/Index") 下载相同的 .wasm
文件,然后在客户端解析路由。
回到你的问题。由于某种原因,您将所有内容从 Blazer WASM 项目 wwwroot/index.html
复制到 Razor Page 项目 Pages/Index.cshtml
。现在你混淆了整个路由系统。当您键入“[...]/counter”时,WASM 路由器会告诉您 .wasm
文件需要从“/Index”下载。同时,Razor Pages 路由器会告诉您已编译的 Index.cshtml
在“/Index”处可用。这会给你 "AmbiguousMatchException: The request matched multiple endpoints. Matches: /Index /Index".
看看 UseBlazorFrameworkFiles
的摘要:
Configures the application to serve Blazor WebAssembly framework files from the root path "/".
解决方法就是保持 WASM 项目中的 index.html
不变。看看默认的 Blazor WASM ASP.Net 应用程序:它同时托管 Blazor WASM、Razor Pages 和 MVC,并且路由很好。
另一种解决方案是使用 UseBlazorFrameworkFiles
的重载,您可以在其中提供路径前缀。例如
app.UseBlazorFrameworkFiles("/wasm");
您将需要修复其他路由。
编辑:
那我们举个例子吧。你有:
- 为页面
/
、/counter
等提供服务的 Blazor WASM 项目
- 一个为页面
/weatherforecast
等提供服务的 Razor 页面项目
现在:
- 您在
/
上启动应用程序。这将从服务器加载 WASM。
- 接下来单击计数器图标。 这不会更改页面!:它显示计数器页面并更新导航 url,但不会加载新页面。
- 现在要去
weatherforecast
。这在 WASM 中找不到,因此实际上从服务器加载了一个新页面。 (剃刀页面或 controller/view)
- 如果您要返回
counter
,在服务器上找不到,因此服务器 'falls-back' 到根目录 (/Index
) 并再次加载 WASM。接下来是查看是否在 WASM 中找到 counter
。
动态 /Index
会破坏这个系统,所以你必须手动解决所有路由。
好的,根据您目前所写的内容,看看 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
。无法直接映射的任何其他内容都在 _host.cshtml
处的 Blazor 服务器应用程序的“范围”中。网站上的所有计划 Razor 页面都按原样提供。您根本不需要 Blazor Server 位,只需回退到默认的 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
. 会得到相同的结果
“标准”Blazor WASM 应用程序托管在静态 HTML 页面内;例如,index.html
。由于某些要求,我想在 Razor 页面应用程序中托管 Blazor。
我所做的是从“标准”Blazor WASM 应用程序开始,删除静态文件,因为我不需要它们,将 index.html
的内容移动到 Wasm.cshtml
,然后更改endpoints.MapFallbackToFile("index.html");
到 endpoints.MapFallbackToPage("/Wasm");
.
一切似乎都在按预期进行;我可以 运行 应用程序并导航到我在 Blazor 中的不同页面。
但是,当我尝试使用 URL 访问页面时,事情就崩溃了;例如,http://mysite/counter
,其中 /counter
是 Blazor 中的一个页面,我收到以下错误:
An unhandled exception occurred while processing the request.
AmbiguousMatchException: The request matched multiple endpoints. Matches:
/Wasm
/Wasm
谁能帮我找出我做错了什么?
P.S.:
- 我在这里查看了一些答案,但我发现的只是人们在谈论 Blazor Server。
- 我正在使用 .NET 3.1 和 Blazor 3.2。
- 我想将我的 Razor Pages 应用程序用于 host/serve Blazor WASM,而不是将它们混合在一个项目中。他们仍然是 2 个不同的项目。
- 我完全知道 Blazor WASM 和 Razor Pages 是不相关的技术。我不是要整合它们。我只是想从动态页面服务器 Blazor WASM 文件。如果它能让您更好地思考我要实现的目标,请将 Razor Pages 视为任何服务器端技术; PHP、Node 或其他任何东西,然后将其应用于我要解决的路由问题。
你提供的信息太少了,所以我不得不做一些猜测。
我猜你的 WASM 集成基于 Blazor WASM ASP.NET 托管模板。该模板由三个项目组成:.Client
项目、.Server
项目和一些具有共享模型的额外项目(他们可能在做清洁架构)。服务器项目是一个 Razor 页面项目,客户端是一个 WASM 项目。
您必须了解的是,Blazor WASM 项目无法与 Razor 页面应用程序相提并论。 Blazor WASM,或者实际上任何 WASM 文件都是一种不同类型的二进制文件,并且在客户端完全运行!它是一个客户端应用程序。 IE。输出二进制文件完全不同。您不能让一个项目同时生成服务器 (x86/arm) 二进制文件和客户端 (WASM) 二进制文件。您需要两个单独的项目。
编译 WASM 项目时实际发生的是,所有页面路由也都转换为 WASM。只需在更改页面时检查网络流量即可。即使您的浏览器 url 发生变化,那也是 假 ... 没有网络流量!事实上,您保持在同一页面上。
现在想一想当您在浏览器中手动输入“[..]/counter”时会发生什么。主机实际上会再次从根目录 ("/" = "/Index") 下载相同的 .wasm
文件,然后在客户端解析路由。
回到你的问题。由于某种原因,您将所有内容从 Blazer WASM 项目 wwwroot/index.html
复制到 Razor Page 项目 Pages/Index.cshtml
。现在你混淆了整个路由系统。当您键入“[...]/counter”时,WASM 路由器会告诉您 .wasm
文件需要从“/Index”下载。同时,Razor Pages 路由器会告诉您已编译的 Index.cshtml
在“/Index”处可用。这会给你 "AmbiguousMatchException: The request matched multiple endpoints. Matches: /Index /Index".
看看 UseBlazorFrameworkFiles
的摘要:
Configures the application to serve Blazor WebAssembly framework files from the root path "/".
解决方法就是保持 WASM 项目中的 index.html
不变。看看默认的 Blazor WASM ASP.Net 应用程序:它同时托管 Blazor WASM、Razor Pages 和 MVC,并且路由很好。
另一种解决方案是使用 UseBlazorFrameworkFiles
的重载,您可以在其中提供路径前缀。例如
app.UseBlazorFrameworkFiles("/wasm");
您将需要修复其他路由。
编辑: 那我们举个例子吧。你有:
- 为页面
/
、/counter
等提供服务的 Blazor WASM 项目 - 一个为页面
/weatherforecast
等提供服务的 Razor 页面项目
现在:
- 您在
/
上启动应用程序。这将从服务器加载 WASM。 - 接下来单击计数器图标。 这不会更改页面!:它显示计数器页面并更新导航 url,但不会加载新页面。
- 现在要去
weatherforecast
。这在 WASM 中找不到,因此实际上从服务器加载了一个新页面。 (剃刀页面或 controller/view) - 如果您要返回
counter
,在服务器上找不到,因此服务器 'falls-back' 到根目录 (/Index
) 并再次加载 WASM。接下来是查看是否在 WASM 中找到counter
。
动态 /Index
会破坏这个系统,所以你必须手动解决所有路由。
好的,根据您目前所写的内容,看看 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
。无法直接映射的任何其他内容都在 _host.cshtml
处的 Blazor 服务器应用程序的“范围”中。网站上的所有计划 Razor 页面都按原样提供。您根本不需要 Blazor Server 位,只需回退到默认的 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
的内容。粘贴 URLhttp://whateveryoursiteis/wasm
. 会得到相同的结果