複数のホストされた ASP.NET Core Blazor WebAssembly アプリ

注意

これは、この記事の最新バージョンではありません。 この記事の最新バージョンについては、.NET 7 バージョンをご参照ください。

この記事では、ホストされた Blazor WebAssembly アプリを複数の Blazor WebAssembly アプリをホストするように構成する方法について説明します。

構成

ポート/ドメイン ホスティング (:5001/:5002firstapp.com/secondapp.com など) またはルート サブパス ホスティング (/FirstApp/SecondApp など) のいずれかで、この記事のホスティング要件に合ったバージョンを選択します。

現在のホスティングの選択で、この記事では、ポート/ドメインのホスティング (:5001/:5002firstapp.com/secondapp.com など) について説明します。

次の例で以下を実行します。

  • ホストされた Blazor WebAssembly アプリのプロジェクト名は、MultipleBlazorApps という名前のフォルダー内の MultipleBlazorApps です。
  • 2 つ目のクライアント アプリが追加される前のソリューション内の 3 つのプロジェクトは、Client フォルダー内の MultipleBlazorApps.ClientServer フォルダー内の MultipleBlazorApps.ServerShared フォルダー内の MultipleBlazorApps.Shared です。
  • 初期 (最初の) クライアント アプリは、Blazor WebAssembly プロジェクト テンプレートから作成されたソリューションの既定のクライアント プロジェクトです。
  • 2 つ目のクライアント アプリは、SecondClient という名前のフォルダー内のソリューション MultipleBlazorApps.SecondClient に追加されます。
  • 必要に応じて、サーバー プロジェクト (MultipleBlazorApps.Server) では、Razor Pages または MVC アプリとしてページまたはビューを提供できます。
  • 最初のクライアント アプリは、ブラウザーで、ポート 5001 で、または firstapp.com のホストでアクセスできます。 2 つ目のクライアント アプリは、ブラウザーで、ポート 5002 で、または secondapp.com のホストでアクセスできます。

現在の選択で、この記事では、ルート サブパス ホスティング (/FirstApp/SecondApp など) について説明します。

次の例で以下を実行します。

  • ホストされた Blazor WebAssembly アプリのプロジェクト名は、MultipleBlazorApps という名前のフォルダー内の MultipleBlazorApps です。
  • 2 つ目のクライアント アプリが追加される前のソリューション内の 3 つのプロジェクトは、Client フォルダー内の MultipleBlazorApps.ClientServer フォルダー内の MultipleBlazorApps.ServerShared フォルダー内の MultipleBlazorApps.Shared です。
  • 初期 (最初の) クライアント アプリは、Blazor WebAssembly プロジェクト テンプレートから作成されたソリューションの既定のクライアント プロジェクトです。
  • 2 つ目のクライアント アプリは、SecondClient という名前のフォルダー内のソリューション MultipleBlazorApps.SecondClient に追加されます。
  • 必要に応じて、サーバー プロジェクト (MultipleBlazorApps.Server) では、正式な Razor Pages または MVC アプリとしてページまたはビューを提供できます。
  • どちらのクライアント アプリも、MultipleBlazorApps.Server プロジェクトの Properties/launchSettings.json ファイルの applicationUrl 値で定義された既定のポートを使用します。 最初のクライアント アプリは、ブラウザーで、/FirstApp サブパスでアクセスできます。 2 番目のクライアント アプリは、ブラウザーで、/SecondApp サブパスでアクセスできます。

この記事に示す例では、次の追加の構成が必要です。

  • 例のホスト ドメイン firstapp.com および secondapp.com でアプリに直接アクセスする。
  • クライアント アプリで TLS/HTTPS セキュリティを有効にするための証明書。
  • 次の機能のために、サーバー アプリを Razor Pages アプリとして構成する。
    • ページまたはビューへの Razor コンポーネントの統合。
    • Razor コンポーネントのプリレンダリング。

上記の構成は、この記事の範囲を超えています。 詳細については、次のリソースを参照してください。

既存のホストされた Blazor WebAssembly ソリューションを使うか、Blazor WebAssembly プロジェクト テンプレートから新しいホストされた Blazor WebAssembly ソリューションを作成します。.NET CLI を使用する場合は -ho|--hosted オプションを渡し、IDE にプロジェクトが作成されている場合は Visual Studio で [ホストされている ASP.NET Core] チェックボックスをオンにします。

MultipleBlazorApps という名前のソリューションのフォルダーを使用して、プロジェクトに MultipleBlazorApps という名前を付けます。

SecondClient という名前のソリューションに新しいフォルダーを作成します。 この新しいフォルダーに、Blazor WebAssembly という名前の 2 番目の MultipleBlazorApps.SecondClientクライアント アプリを追加します。 プロジェクトをスタンドアロン Blazor WebAssembly アプリとして追加します。 スタンドアロンの Blazor WebAssembly アプリを作成するには、.NET CLI を使用する場合は -ho|--hosted オプションを渡さないでください。また、Visual Studio を使用する場合は [ホストされている ASP.NET Core] チェックボックスを使用しないでください。

MultipleBlazorApps.SecondClient プロジェクトに次の変更を適用します。

  • Client/Pages フォルダーから SecondClient/Pages フォルダーに FetchData コンポーネント (Pages/FetchData.razor) をコピーします。 スタンドアロンの Blazor WebAssembly アプリで気象データ用に Server プロジェクトのコントローラーを呼び出さず、静的データ ファイルを使用するため、この手順が必要です。 FetchData コンポーネントを追加されたプロジェクトにコピーすることで、2 番目のクライアント アプリも、気象データ用のサーバー API への Web API 呼び出しを行います。
  • SecondClient/wwwroot/sample-data フォルダー内の weather.json ファイルが使用されていないため、フォルダーを削除します。

次の表は、SecondClient フォルダーと MultipleBlazorApps.SecondClient プロジェクトが追加された後のソリューションのフォルダーとプロジェクト名を示しています。

物理フォルダー プロジェクト名 説明
Client MultipleBlazorApps.Client Blazor WebAssembly クライアント アプリ
SecondClient MultipleBlazorApps.SecondClient Blazor WebAssembly クライアント アプリ
Server MultipleBlazorApps.Server ASP.NET Core サーバー アプリ
Shared MultipleBlazorApps.Shared 共有リソース プロジェクト

MultipleBlazorApps.Server プロジェクトは、2 つの Blazor WebAssembly クライアント アプリを提供し、MVC コントローラーを介してクライアント アプリの FetchData コンポーネントに気象データを提供します。 必要に応じて、MultipleBlazorApps.Server プロジェクトで、従来の Razor Pages または MVC アプリとしてページまたはビューを提供することもできます。 ページまたはビューの提供を有効にする手順については、この記事で後述します。

注意

この記事のデモでは、MultipleBlazorApps.Client プロジェクトに FirstAppMultipleBlazorApps.SecondClient プロジェクトに SecondApp の静的な Web 資産パス名を使用します。 "FirstApp" と "SecondApp" という名前は、単にデモンストレーションを目的としています。 App1/App2Client1/Client21/2、または同様の名前付けスキームなど、クライアント アプリを区別するために他の名前を使用できます。

ポートまたはドメインからクライアント アプリに要求をルーティングする場合、"FirstApp" と "SecondApp" は、静的資産に対する要求のルーティングと応答の提供に "内部的" に使用され、ブラウザーのアドレス バーには表示されません。

注意

この記事のデモでは、MultipleBlazorApps.Client プロジェクトに FirstAppMultipleBlazorApps.SecondClient プロジェクトに SecondApp の静的な Web 資産パス名を使用します。 "FirstApp" と "SecondApp" という名前は、単にデモンストレーションを目的としています。 App1/App2Client1/Client21/2、または同様の名前付けスキームなど、クライアント アプリを区別するために他の名前を使用できます。

"FirstApp" と "SecondApp" は、要求がこれらの名前を使用して 2 つのクライアント アプリにルーティングされるため、ブラウザーのアドレス バーにも表示されます。 その他の有効な URL ルート セグメントがサポートされており、ルート セグメントは、静的 Web 資産を内部的にルーティングするために使用される名前と厳密に一致する必要はありません。 この記事の例で内部の静的資産ルーティングとアプリ要求ルーティングの両方に "FirstApp" と "SecondApp" を使用するのは、単に便宜的なものです。

クライアント アプリの最初のプロジェクト ファイル (MultipleBlazorApps.Client.csproj) で、<PropertyGroup> に値が FirstApp<StaticWebAssetBasePath> プロパティを追加して、プロジェクトの静的資産の基本パスを設定します。

<StaticWebAssetBasePath>FirstApp</StaticWebAssetBasePath>

MultipleBlazorApps.SecondClient アプリのプロジェクト ファイル (MultipleBlazorApps.SecondClient.csproj) 内で:

  • 値が SecondApp<StaticWebAssetBasePath> プロパティを <PropertyGroup> に追加します。

    <StaticWebAssetBasePath>SecondApp</StaticWebAssetBasePath>
    
  • MultipleBlazorApps.Shared のプロジェクト参照を <ItemGroup> に追加します。

    <ItemGroup>
      <ProjectReference Include="..\Shared\MultipleBlazorApps.Shared.csproj" />
    </ItemGroup>
    

サーバー アプリのプロジェクト ファイル (Server/MultipleBlazorApps.Server.csproj) で、追加した MultipleBlazorApps.SecondClient クライアント アプリに対するプロジェクト参照を <ItemGroup> に作成します。

<ProjectReference Include="..\SecondClient\MultipleBlazorApps.SecondClient.csproj" />

サーバー アプリの Properties/launchSettings.json ファイルで、ポート 5001 と 5002 でクライアント アプリにアクセスするように、Kestrel プロファイル (MultipleBlazorApps.Server) の applicationUrl を構成します。 ローカル環境で例のドメインを使用するように構成した場合、applicationUrl の URL で firstapp.comsecondapp.com を使用でき、ポートを使用しません。

注意

このデモでは、ポートを使用することで、ローカル ブラウザーでクライアント プロジェクトにアクセスできます。Web ブラウザーがホスト構成 (firstapp.comsecondapp.com) を介してクライアント アプリにアクセスできるように、ローカル ホスティング環境を構成する必要はありません。 運用シナリオでは、サブドメインを使用してクライアント アプリを区別するのが一般的な構成です。

たとえば次のような点です。

  • このデモの構成からポートを削除します。
  • サブドメインを使用するようにホストを変更します (サイト訪問者用の www.contoso.com、管理者用の admin.contoso.com、など)。
  • 追加のクライアント アプリに対して追加のホストを含めることができます。サーバー アプリがページまたはビューを提供する Razor Pages または MVC アプリでもある場合は、少なくとももう 1 つのホストが必要です。

サーバー アプリからページまたはビューを提供する予定の場合は、Properties/launchSettings.json ファイルで次 applicationUrl の設定を使用します。これにより、次のアクセスが許可されます。

  • 必要に応じて、Razor Pages または MVC アプリ (MultipleBlazorApps.Server プロジェクト) がポート 5000 で要求に応答する。
  • 最初のクライアント (MultipleBlazorApps.Client) への要求に対する応答がポート 5001 で行われる。
  • 2 番目のクライアント (MultipleBlazorApps.SecondClient) への要求に対する応答がポート 5002 で行われる。
"applicationUrl": "https://localhost:5000;https://localhost:5001;https://localhost:5002",

サーバー アプリでページまたはビューを提供する予定がなく、Blazor WebAssembly クライアント アプリのみを提供する予定の場合は、次の設定を使用します。これにより、次のアクセスが許可されます。

  • 最初のクライアント アプリがポート 5001 で応答する。
  • 2 つ目のクライアント アプリがポート 5002 で応答する。
"applicationUrl": "https://localhost:5001;https://localhost:5002",

サーバー アプリの Program.cs ファイルで、UseHttpsRedirection の呼び出しの後に現れる次のコードを削除します。

  • サーバー アプリからページまたはビューを提供する予定の場合は、次のコード行を削除します。

    - app.UseBlazorFrameworkFiles();
    
    - app.MapFallbackToFile("index.html");
    
  • サーバー アプリで Blazor WebAssembly クライアント アプリのみを提供する予定の場合は、次のコードを削除します。

    - app.UseBlazorFrameworkFiles();
    
    ...
    
    - app.UseRouting();
    
    - app.MapRazorPages();
    - app.MapControllers();
    - app.MapFallbackToFile("index.html");
    

    静的ファイル ミドルウェアはそのままにします。

    app.UseStaticFiles();
    
  • 要求をクライアント アプリにマップするミドルウェアを追加します。 次の例では、要求ポートが最初のクライアント アプリの場合は 5001、2 番目のクライアント アプリの場合は 5002、または要求ホストが最初のクライアント アプリの場合は firstapp.com、2 番目のクライアント アプリの場合は secondapp.com のときに実行するようにミドルウェアを構成します。

    注意

    ローカル ブラウザーでローカル システム上のホスト (firstapp.com/secondapp.com) を使用するには、この記事の範囲外である追加の構成が必要です。 このシナリオのローカル テストには、ポートを使用することをお勧めします。 一般的な運用アプリは、サブドメインを使用するように構成されます (サイト訪問者用の www.contoso.com、管理者用の admin.contoso.com、など)。 適切な DNS とサーバー構成を使用すると (これはこの記事の範囲を超え、使用されるテクノロジに依存します)、アプリは次のコードで名前が付けられている任意のホストで要求に応答します。

    Program.cs から app.UseBlazorFrameworkFiles(); 行を削除した場所に、次のコードを配置します。

    app.MapWhen(ctx => ctx.Request.Host.Port == 5001 || 
        ctx.Request.Host.Equals("firstapp.com"), first =>
    {
        first.Use((ctx, nxt) =>
        {
            ctx.Request.Path = "/FirstApp" + ctx.Request.Path;
            return nxt();
        });
    
        first.UseBlazorFrameworkFiles("/FirstApp");
        first.UseStaticFiles();
        first.UseStaticFiles("/FirstApp");
        first.UseRouting();
    
        first.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
            endpoints.MapFallbackToFile("/FirstApp/{*path:nonfile}", 
                "FirstApp/index.html");
        });
    });
    
    app.MapWhen(ctx => ctx.Request.Host.Port == 5002 || 
        ctx.Request.Host.Equals("secondapp.com"), second =>
    {
        second.Use((ctx, nxt) =>
        {
            ctx.Request.Path = "/SecondApp" + ctx.Request.Path;
            return nxt();
        });
    
        second.UseBlazorFrameworkFiles("/SecondApp");
        second.UseStaticFiles();
        second.UseStaticFiles("/SecondApp");
        second.UseRouting();
    
        second.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
            endpoints.MapFallbackToFile("/SecondApp/{*path:nonfile}", 
                "SecondApp/index.html");
        });
    });
    

    警告

    HttpRequest.HostRequireHost などのホスト ヘッダーに依存する API は、クライアントによるスプーフィングの対象になる可能性があります。

    ホストとポートのスプーフィングを防ぐには、次のいずれかの方法を使用します。

  • 要求をクライアント アプリにマップするミドルウェアを追加します。 次の例では、要求サブパスが、最初のクライアント アプリの場合は /FirstApp、2 番目のクライアント アプリの場合は /SecondApp のときに実行するようにミドルウェアを構成します。

    Program.cs から app.UseBlazorFrameworkFiles(); 行を削除した場所に、次のコードを配置します。

    app.MapWhen(ctx => ctx.Request.Path.StartsWithSegments("/FirstApp", 
        StringComparison.OrdinalIgnoreCase), first =>
    {
        first.UseBlazorFrameworkFiles("/FirstApp");
        first.UseStaticFiles();
        first.UseStaticFiles("/FirstApp");
        first.UseRouting();
    
        first.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
            endpoints.MapFallbackToFile("/FirstApp/{*path:nonfile}",
                "FirstApp/index.html");
        });
    });
    
    app.MapWhen(ctx => ctx.Request.Path.StartsWithSegments("/SecondApp", 
        StringComparison.OrdinalIgnoreCase), second =>
    {
        second.UseBlazorFrameworkFiles("/SecondApp");
        second.UseStaticFiles();
        second.UseStaticFiles("/SecondApp");
        second.UseRouting();
    
        second.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
            endpoints.MapFallbackToFile("/SecondApp/{*path:nonfile}",
                "SecondApp/index.html");
        });
    });
    
  • 各クライアント アプリで基本パスを設定します。

    最初のクライアント アプリの index.html ファイル (Client/wwwroot/index.html) で、サブパスを反映するように <base> タグ値を更新します。 末尾にスラッシュが必要です。

    <base href="/FirstApp/" />
    

    2 番目のクライアント アプリの index.html ファイル (SecondClient/wwwroot/index.html) で、サブパスを反映するように <base> タグ値を更新します。 末尾にスラッシュが必要です。

    <base href="/SecondApp/" />
    

UseStaticFiles について詳しくは、「ASP.NET Core Blazor の静的ファイル」をご覧ください。

UseBlazorFrameworkFiles および MapFallbackToFile の詳細については、次のリソースを参照してください。

注意

通常、.NET 参照ソースへのドキュメント リンクを使用すると、リポジトリの既定のブランチが読み込まれます。このブランチは、.NET の次回リリースに向けて行われている現在の開発を表します。 特定のリリースのタグを選択するには、[Switch branches or tags](ブランチまたはタグの切り替え) ドロップダウン リストを使います。 詳細については、「ASP.NET Core ソース コードのバージョン タグを選択する方法」 (dotnet/AspNetCore.Docs #26205) を参照してください。

クライアント アプリからサーバー API 内の /WeatherForecast への要求は、どのクライアント アプリが要求を行うかによって、/FirstApp/WeatherForecast または /SecondApp/WeatherForecast のいずれかになります。 そのため、サーバー API から気象データを返すコントローラー ルートに、パス セグメントを含める変更が必要です。

サーバー アプリの天気予報コントローラー (Controllers/WeatherForecastController.cs) で、WeatherForecastController への既存のルート ([Route("[controller]")]) をクライアント要求パスを考慮した次のルートに置き換えます。

[Route("FirstApp/[controller]")]
[Route("SecondApp/[controller]")]

サーバー アプリからページを提供する予定の場合は、サーバー アプリの Pages フォルダーに IndexRazor ページを追加します。

Pages/Index.cshtml:

@page
@model MultipleBlazorApps.Server.Pages.IndexModel
@{
    ViewData["Title"] = "Home";
}

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <title>Home</title>
</head>
<body>
    <div class="main">
        <div class="content px-4">

            <div>
                <h1>Welcome</h1>
                <p>Hello from Razor Pages!</p>
            </div>
        </div>
    </div>
</body>
</html>

Pages/Index.cshtml.cs:

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace MultipleBlazorApps.Server.Pages;

public class IndexModel : PageModel
{
    public void OnGet()
    {
    }
}
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace MultipleBlazorApps.Server.Pages
{
    public class IndexModel : PageModel
    {
        public void OnGet()
        {
        }
    }
}

注意

上記の Index ページは、純粋にデモンストレーションを目的とした最小限の例です。 アプリに追加の Razor Pages 資産 (レイアウト、スタイル、スクリプト、インポートなど) が必要な場合は、Razor Pages プロジェクト テンプレートから作成されたアプリから取得します。 詳細については、「ASP.NET Core での Razor Pages の概要」を参照してください。

サーバー アプリから MVC ビューを提供する予定の場合は、Index ビューと Home コントローラーを追加します。

Views/Home/Index.cshtml:

@{
    ViewData["Title"] = "Home";
}

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <title>Home</title>
</head>
<body>
    <div class="main">
        <div class="content px-4">

            <div>
                <h1>Welcome</h1>
                <p>Hello from MVC!</p>
            </div>
        </div>
    </div>
</body>
</html>

Controllers/HomeController.cs:

using Microsoft.AspNetCore.Mvc;

namespace MultipleBlazorApps.Server.Controllers;

public class HomeController : Controller
{
    public IActionResult Index() => View();
}

注意

上記の Index ビューは、純粋にデモンストレーションを目的とした最小限の例です。 アプリに追加の MVC 資産 (レイアウト、スタイル、スクリプト、インポートなど) が必要な場合は、MVC プロジェクト テンプレートから作成されたアプリから取得します。 詳細については、「ASP.NET Core MVC の概要」を参照してください。

いずれかのクライアント アプリからサーバー アプリのページまたはビューで Razor コンポーネントを使用する方法について詳しくは、「ASP.NET Core Razor コンポーネントのプリレンダリングと統合を行う」を参照してください。

アプリを実行する

MultipleBlazorApps.Server プロジェクトを実行します。

  • https://localhost:5001 で最初のクライアント アプリにアクセスします。
  • https://localhost:5002 で追加したクライアント アプリにアクセスします。
  • サーバー アプリがページまたはビューを提供するように構成されている場合は、Index ページにアクセスするか、https://localhost:5000 で表示します。
  • https://localhost:{DEFAULT PORT}/FirstApp で最初のクライアント アプリにアクセスします。
  • https://localhost:{DEFAULT PORT}/SecondApp で追加したクライアント アプリにアクセスします。
  • サーバー アプリがページまたはビューを提供するように構成されている場合は、Index ページにアクセスするか、https://localhost:{DEFAULT PORT} で表示します。

上記の URL の例では、{DEFAULT PORT} プレースホルダーは、MultipleBlazorApps.Server プロジェクトの Properties/launchSettings.json ファイルの applicationUrl 値で定義された既定のポートです。

重要

dotnet watch (または dotnet run) コマンド (.NET CLI) を使用してアプリを実行する場合は、コマンド シェルがソリューションの Server フォルダーで開いていることを確認します。

Visual Studio のスタート ボタンを使ってアプリを実行する場合は、MultipleBlazorApps.Server プロジェクトがスタートアップ プロジェクトとして設定されていることを確認します (ソリューション エクスプローラーで強調表示されています)。

静的な資産

資産がクライアント アプリの wwwroot フォルダー内にある場合は、コンポーネントに静的な資産の要求パスを指定します。

<img alt="..." src="{PATH AND FILE NAME}" />

{PATH AND FILE NAME} プレースホルダーは、wwwroot の下のパスとファイル名です。

たとえば、wwwrootvehicle フォルダー内にある Jeep の画像 (jeep-yj.png) のソースは次のようになります。

<img alt="Jeep Wrangler YJ" src="vehicle/jeep-yj.png" />

Razor クラス ライブラリ (RCL) のサポート

新しいプロジェクトとしてソリューションに Razor クラス ライブラリ (RCL) を追加します。

  • ソリューション エクスプローラーで、ソリューションを右クリックし、[追加]>[新しいプロジェクト] の順に選択します。
  • Razor クラス ライブラリ プロジェクト テンプレートを使用して、プロジェクトを作成します。 このセクションの例では、プロジェクト名 ComponentLibrary を使用します。これは RCL のアセンブリ名でもあります。 [サポート ページとビュー] チェックボックスはオンにしないでください。

ホストされた Blazor WebAssembly クライアント アプリごとに、RCL プロジェクトのプロジェクト参照を作成します。それには、ソリューション エクスプローラーで各クライアント プロジェクトを右クリックし、[追加]>[プロジェクト参照] の順に選択します。

次のいずれかの方法で、クライアント アプリで RCL のコンポーネントを使用します。

  • RCL の名前空間用にコンポーネントの先頭に @using ディレクティブを配置し、コンポーネントの Razor 構文を追加します。 ComponentLibrary というアセンブリ名を持つ RCL の例を次に示します。

    @using ComponentLibrary
    
    ...
    
    <Component1 />
    
  • コンポーネントの Razor 構文と共に RCL の名前空間を指定します。 この方法では、コンポーネント ファイルの先頭に @using ディレクティブは必要ありません。 ComponentLibrary というアセンブリ名を持つ RCL の例を次に示します。

    <ComponentLibrary.Component1 />
    

注意

@using ディレクティブを各クライアント アプリの _Import.razor ファイルに配置することもできます。これにより、RCL の名前空間が、そのプロジェクト内のコンポーネントでグローバルに使用できるようになります。

他の静的な資産が RCL の wwwroot フォルダー内にある場合は、ASP.NET Core でのクラス ライブラリの再利用可能な Razor UI に関する記事のガイダンスに従って、クライアント アプリで静的な資産を参照します。

<img alt="..." src="_content/{PACKAGE ID}/{PATH AND FILE NAME}" />

{PACKAGE ID} プレースホルダーは、RCL のパッケージ ID です。 プロジェクト ファイルで <PackageId> が指定されていない場合、パッケージ ID の既定値はプロジェクトのアセンブリ名になります。 {PATH AND FILE NAME} プレースホルダーは、wwwroot の下のパスとファイル名です。

次の例は、RCL の wwwroot フォルダーの vehicle フォルダー内にある Jeep 画像 (jeep-yj.png) のマークアップを示しています。 ComponentLibrary というアセンブリ名を持つ RCL の例を次に示します。

<img alt="Jeep Wrangler YJ" src="_content/ComponentLibrary/vehicle/jeep-yj.png" />

その他のリソース