ASP.NET Core Blazor 应用基路径

注释

此版本不是本文的最新版本。 要查看当前版本,请参阅本文的.NET 9 版本

警告

此版本的 ASP.NET Core 不再受支持。 有关详细信息,请参阅 .NET 和 .NET Core 支持策略。 要查看当前版本,请参阅本文的.NET 9 版本

重要

此信息与预发布产品相关,相应产品在商业发布之前可能会进行重大修改。 Microsoft对此处提供的信息不作任何明示或暗示的保证。

要查看当前版本,请参阅本文的.NET 9 版本

本文介绍 ASP.NET Core 应用中Blazor,包括配置指南。

应用基路径是应用的根 URL 路径。 在 Blazor 应用中实现成功路由需要为任何不是默认应用基路径的根 URL 路径/进行框架配置。

请考虑以下 ASP.NET 核心应用和 Blazor 子应用:

  • ASP.NET Core 应用命名 MyApp
    • 应用在物理上驻留在 d:/MyApp.
    • 收到的请求在 https://www.contoso.com/{MYAPP RESOURCE}.
  • 一个名为 Blazor 的应用是 CoolApp 的子应用 MyApp
    • 子应用在物理上驻留在 d:/MyApp/CoolApp.
    • 收到的请求在 https://www.contoso.com/CoolApp/{COOLAPP RESOURCE}.

如果不指定 CoolApp其他配置,此方案中的子应用就不知道它驻留在服务器上的位置。 例如,应用程序必须知道它所在的相对 URL 路径 /CoolApp/,否则无法为其资源构造正确的相对 URL。 当应用未托管在根 URL 路径上时,此方案也适用于各种托管和反向代理方案。

背景

锚点标签的目标(href)可以由两个端点之一组成:

  • 包含scheme(如果省略,则默认为页面的scheme)的绝对位置、主机、端口和路径,或仅为正斜杠(/)后加路径。

    示例: https://example.com/a/b/c/a/b/c

  • 仅包含路径且不以正斜杠开头的相对位置(/)。 这些解析是相对于当前文档的 URL 或者 <base> 标签的值(如果有指定)来进行的。

    示例:a/b/c

配置的应用基路径中存在尾部斜杠(/)对于计算应用 URL 的基本路径非常重要。 例如,https://example.com/a 的基路径是 https://example.com/,而以斜杠结尾的 https://example.com/a/ 的基路径是 https://example.com/a

在 ASP.NET Core 应用中与 Blazor 相关的链接源:

  • 组件 (Razor) 中的 .razor URL 通常是相对的。
  • 脚本中的 URL(如 Blazor 脚本 blazor.*.js)是相对于文档的。
  • 手动写入 _Host.cshtml 文件中的 URL(Blazor Server如果要在不同的文档中呈现),应始终是绝对的。
  • 组件 (Razor) 中的 .razor URL 通常是相对的。
  • 脚本中的 URL(如 Blazor 脚本 blazor.*.js)是相对于文档的。

如果要从不同的文档(例如Blazor,和/Admin/B/C/)呈现/Admin/D/E/应用,则必须考虑到应用基路径,或者当应用在每个文档中呈现并且从错误的 URL 提取资源时,基本路径会有所不同。

有两种方法可以正确解决相对链接的问题:

  • 使用将文档作为根的方式动态映射资源。
  • 为文档设置一致的基路径,并映射该基路径下的资源。

第一个选项更为复杂,并不是最典型的方法,因为它使每个文档的导航变得不同。 请考虑以下示例来呈现页面 /Something/Else

  • /Admin/B/C/ 环境下渲染,页面以路径 /Admin/B/C/Something/Else 被渲染。
  • /Admin/D/E/渲染下,页面在同一路径/Admin/B/C/Something/Else处被渲染。

在第一种方法下,路由提供 IDynamicEndpointMetadataMatcherPolicy组合在一起是实现完全动态的解决方案的基础,该解决方案可在运行时确定请求的路由方式。

对于第二个选项(即通常采用的方法),应用在文档中设置基本路径,并将服务器终结点映射到基础下的路径。 以下指南采用此方法。

服务器端 Blazor

将服务器端SignalR应用的中心通过Blazor映射,将路径传递到MapBlazorHub中的Program文件中:

app.MapBlazorHub("base/path");

使用 MapBlazorHub 的好处是,你可以映射模式,例如 "{tenant}" ,而不仅仅是具体路径。

当应用位于具有SignalR的虚拟文件夹中时,还可以映射中心。 在以下示例中,请求 /base/path/ 由 Blazor 的 SignalR 集线器处理:

app.Map("/base/path/", subapp => {
    subapp.UsePathBase("/base/path/");
    subapp.UseRouting();
    subapp.UseEndpoints(endpoints => endpoints.MapBlazorHub());
});

根据“<base>”部分中的指南配置标记。

托管 Blazor WebAssembly

如果应用是托管 Blazor WebAssembly 的应用:

  • Server 项目中(Program.cs):
    • 请调整UseBlazorFrameworkFiles的路径(例如app.UseBlazorFrameworkFiles("/base/path");)。
    • 配置对 UseStaticFiles (例如, app.UseStaticFiles("/base/path");) 的调用。
  • Client 项目中:
    • 在项目文件中配置 <StaticWebAssetBasePath> 以匹配提供静态 Web 资产的路径(例如, <StaticWebAssetBasePath>base/path</StaticWebAssetBasePath> )。
    • 根据“<base>”部分中的指南配置标记。

有关在托管Blazor WebAssembly解决方案中托管多个Blazor WebAssembly应用的示例,请参阅多个托管 ASP.NET 核心Blazor WebAssembly应用,其中介绍了多个客户端应用的域/端口托管和子路径托管Blazor WebAssembly的方法。

独立 Blazor WebAssembly

在独立Blazor WebAssembly应用中,按<base>部分的指南,仅配置标记。

配置应用基路径

若要为 Blazor 应用的基路径 https://www.contoso.com/CoolApp/提供配置,请设置 应用基路径 (<base>),该路径也称为相对根路径。

通过配置应用基路径,不在根目录中的组件可以构造相对于应用根路径的 URL。 不同级别的目录结构的组件可以在整个应用中生成指向其他资源的链接。 应用基路径还用于拦截目标位于应用基路径 URI 空间内的特定超链接 href 。 组件 Router 处理内部导航。

<base> 标签置于 <head> 标记(<head> 内容的位置 )前,并置于任何具有 URL 属性值的元素之前,例如 href 元素的 <link> 属性。

在许多托管方案中,应用的相对 URL 路径是应用的根目录。 在这些默认情况下,应用的相对 URL 基路径配置为/<base href="/" />内容中<head>

在许多托管方案中,应用的相对 URL 路径是应用的根目录。 默认情况下,应用的相对 URL 基路径在内容<head>中的表达如下:

  • Blazor Server: ~/ 配置为 <base href="~/" />.
  • Blazor WebAssembly: / 配置为 <base href="/" />.

注释

在某些托管方案中,例如 GitHub Pages 和 IIS 子应用,必须将应用基路径设置为服务器的相对 URL 路径。

  • 在服务器端 Blazor 应用中,使用以下 一方法:

    • 选项 1:使用<base>标记设置应用的基本路径(内容位置<head>):

      <base href="/CoolApp/">
      

      尾部斜杠是必需的。

    • 选项2:在UsePathBase生成后立即在应用的请求处理管道()中调用,以配置与请求路径交互的任何后续中间件的基路径,Program.cs

      app.UsePathBase("/CoolApp");
      

      建议调用UsePathBase,当您也希望在本地运行Blazor Server应用时。 例如,在Properties/launchSettings.json中提供启动 URL。

      "launchUrl": "https://localhost:{PORT}/CoolApp",
      

      {PORT}前面的示例中的占位符是与配置路径中的安全端口匹配的applicationUrl端口。 以下示例演示端口 7279 上应用的完整启动配置文件:

      "BlazorSample": {
        "commandName": "Project",
        "dotnetRunMessages": true,
        "launchBrowser": true,
        "applicationUrl": "https://localhost:7279;http://localhost:5279",
        "launchUrl": "https://localhost:7279/CoolApp",
        "environmentVariables": {
          "ASPNETCORE_ENVIRONMENT": "Development"
      }
      

      有关 launchSettings.json 文件的详细信息,请参阅 在 ASP.NET Core 中使用多个环境。 有关Blazor 应用基本路径和托管的其他信息,请参阅 <base href="/" /> 或 base 标记的替代方案以用于 Blazor MVC 集成(dotnet/aspnetcore #43191)。

  • 独立 Blazor WebAssembly (wwwroot/index.html):

    <base href="/CoolApp/">
    

    尾部斜杠是必需的。

  • 托管Blazor WebAssembly(Client项目,wwwroot/index.html):

    <base href="/CoolApp/">
    

    尾部斜杠是必需的。

    项目中,在构建完成后<立即调用直接在应用的请求处理管道()中,配置与请求路径交互的后续中间件的基路径:

    app.UsePathBase("/CoolApp");
    

注释

使用 WebApplication(请参阅 从 .NET 5 中的 ASP.NET Core 迁移到 .NET 6)时,必须在调用 app.UseRouting 之后再调用 UsePathBase,以便路由中间件可以在匹配路由之前观察修改的路径。 否则,在 UsePathBase 重写路径之前匹配路由,如中间件排序路由文章中所述。

不要在整个应用中使用正斜杠为链接添加前缀。 避免使用路径段分隔符或使用点斜杠 (./) 相对路径表示法:

  • 不對: <a href="/account">
  • 正确: <a href="account">
  • 正确: <a href="./account">

Blazor WebAssembly 服务 HttpClient Web API 请求中,确认 JSON 帮助程序(HttpClientJsonExtensions)不要将 URL 作为正斜杠前缀(/):

  • 不對: var rsp = await client.GetFromJsonAsync("/api/Account");
  • 正确: var rsp = await client.GetFromJsonAsync("api/Account");

不要为 导航管理器 相对链接加上正斜杠的前缀。 避免使用路径段分隔符或使用点斜杠(./)相对路径表示法(Navigation 是一个被插入的NavigationManager):

  • 不對: Navigation.NavigateTo("/other");
  • 正确: Navigation.NavigateTo("other");
  • 正确: Navigation.NavigateTo("./other");

在 Azure/IIS 托管的典型配置中,通常不需要其他配置。 在某些非 IIS 托管和反向代理托管方案中,可能需要其他静态文件中间件配置:

  • 正确提供静态文件(例如 app.UseStaticFiles("/CoolApp");)。
  • 为脚本提供服务 Blazor (_framework/blazor.*.js)。 有关详细信息,请参阅 ASP.NET 核心 Blazor 静态文件

Blazor WebAssembly对于具有非根相对 URL 路径(例如)的应用,<base href="/CoolApp/">应用在本地运行时找不到其资源。 在本地开发和测试期间,为了解决这个问题,您可以提供一个路径基参数,该参数与运行时href标签的<base>值匹配。 不要包含尾部斜杠。 若要在本地运行应用时传递路径基参数,请从应用的目录中使用dotnet watch选项来执行 dotnet run (或 --pathbase) 命令。

dotnet watch --pathbase=/{RELATIVE URL PATH (no trailing slash)}

Blazor WebAssembly对于具有相对 URL 路径/CoolApp/的应用,命令是:<base href="/CoolApp/">

dotnet watch --pathbase=/CoolApp

如果您希望将应用的启动配置文件配置为自动指定pathbase,而不是使用dotnet watch(或dotnet run)手动指定,请在commandLineArgs中设置Properties/launchSettings.json属性。 下面也可以配置启动 URL(launchUrl):

"commandLineArgs": "--pathbase=/{RELATIVE URL PATH (no trailing slash)}",
"launchUrl": "{RELATIVE URL PATH (no trailing slash)}",

使用 CoolApp 作为示例:

"commandLineArgs": "--pathbase=/CoolApp",
"launchUrl": "CoolApp",

dotnet watch(或dotnet run)与设置基本路径的--pathbase选项或启动配置文件结合使用,Blazor WebAssembly应用程序将在http://localhost:port/CoolApp本地响应。

有关 launchSettings.json 文件的详细信息,请参阅 在 ASP.NET Core 中使用多个环境。 有关Blazor 应用基本路径和托管的其他信息,请参阅 <base href="/" /> 或 base 标记的替代方案以用于 Blazor MVC 集成(dotnet/aspnetcore #43191)。

从配置中获取应用基路径

以下指南介绍如何从应用设置文件中获取<base>标记的路径,适用于不同的环境

将应用设置文件添加到应用。 以下示例适用于 Staging 环境(appsettings.Staging.json):

{
  "AppBasePath": "staging/"
}

在服务器端Blazor应用中,从内容中的<head>配置加载基本路径:

@inject IConfiguration Config

...

<head>
    ...
    <base href="/@(Config.GetValue<string>("AppBasePath"))" />
    ...
</head>

或者,服务器端应用可以从配置中 UsePathBase获取值。 将以下代码首先放在应用的请求处理管道中,紧接在Program.cs生成WebApplicationBuilder之后builder.Build()。 以下示例使用配置键 AppBasePath

app.UsePathBase($"/{app.Configuration.GetValue<string>("AppBasePath")}");

在客户端应用 Blazor WebAssembly 中:

  • 请从<base>中移除wwwroot/index.html标记。

    - <base href="..." />
    
  • 通过 HeadContent 组件 中的 App 组件提供应用基路径(App.razor):

    @inject IConfiguration Config
    
    ...
    
    <HeadContent>
        <base href="/@(Config.GetValue<string>("AppBasePath"))" />
    </HeadContent>
    

如果没有要加载的配置值,例如,在非暂存环境中,上述 href 值将解析为根路径 /

本节中的示例侧重于从应用设置提供应用基路径,但从 IConfiguration 中读取路径的方法对任何配置提供程序都有效。 有关详细信息,请参阅以下资源: