サイト管理者
PowerPortalsProは、SystemUser支援の管理者がホストを再起動せずにサーバー側のキャッシュをクリアできるSite Adminページを提供しています。フレームワークはキャッシュクリアAPI(IPowerPortalsProService.ClearAllCachesAsync / ClearCacheAsync)を提供します。ポータルはページ自体、ロールゲート、ナビリンクを提供します。
配線
接続すべきものは3つあります:ロールクレームトランス、ページ自体、そしてナビエントリーです。ポータルテンプレート(Auto、WebAssembly、Serverのインタラクティブオプションpowerportalspro-csharp)は、3つすべてを箱から出荷します。下のスニペットはテンプレートが発信する内容を反映しているため、テンプレートから生成されていないポータルに持ち上げることができます。
1. どのDataverseロールが管理者権限を与えるかを設定する
SystemAdminClaimsTransformer組み込みの System Administrator Dataverse ロールまたはPortalIdentityOptions.SystemAdminRoleNameによって設定されたカスタムロールを持つ任意のプリンシパルに合成 SystemAdmin ロールの主張を刻印します。組み込みの役割は常に管理者として扱われます。設定された役割はオプションで、その上にレイヤーがあります。UI認可([Authorize(Roles = "SystemAdmin")]および<AuthorizeView Roles="SystemAdmin">)は合成クレームをチェックするため、カスタムDataverseロールに管理権限を与えても、ラザーコードに触れずに許可されます。
// appsettings.json — 任意です。組み込みの「システム管理者」の所有者
// Dataverseの役割は常にポータル管理者として扱われます。SystemAdminRoleNameレイヤー
// さらにDataverseの役割も加わりました。
{
"PortalIdentity": {
"SystemAdminRoleName": "ポータル管理者"
}
}
// Program.cs
builder.Services.Configure<PortalIdentityOptions>(
builder.Configuration.GetSection("PortalIdentity"));
builder.Services.AddSingleton<IClaimsTransformation, SystemAdminClaimsTransformer>();
2. サイト管理者ページを追加する
[Authorize(Roles = "SystemAdmin")]属性はAuthorizeRouteViewによって尊重され、内側の<AuthorizeView Roles="SystemAdmin">はホストがルーターを交換した場合に備えた防御深層(defence-in-depth)です。ページ全体(すべてクリアボタン、キャッシュごとのローカライズされた説明付きリスト、トーストのフィードバック付き)はテンプレートのSiteAdmin.razorに収まっています。
@attribute [Route("admin/site-admin")]
@attribute [Authorize(Roles = "SystemAdmin")]
@inject IPowerPortalsProService _powerPortalsProService
@inject IToastService _toastService
<AuthorizeView Roles="SystemAdmin">
<Authorized>
</Authorized>
</AuthorizeView>
3. ナビゲーションに表面化
管理者ナビグループを <AuthorizeView Roles="SystemAdmin"> で囲んで、非管理者が追跡できないリンクを見られないようにしましょう。リンクターゲットは、ページが登録するルートです。
<AuthorizeView Roles="SystemAdmin">
<Authorized>
<FluentNavGroup Title="管理" Icon="@(new Size20.WrenchSettings())">
<FluentNavLink Href="admin/site-admin"
Icon="@(new Size20.LauncherSettings())">
サイト管理者
</FluentNavLink>
</FluentNavGroup>
</Authorized>
</AuthorizeView>
キャッシュされるもの
フレームワークは9つのキャッシュを IClearableCacheとして登録し、サイト管理者ページでそれらをアルファベット順に並べ替え、各キャッシュの横にローカライズされた説明が付けられています。説明はフレームワークの ppp-server.defaults.en.json に含まれ app.cache-descriptions。
- TableMetadata — テーブルごとのメタデータ(列、型、選択オプション、関係)。スキーマの変更後にリフレッシュしてください。
- ViewMetadata — キャッシュされたDataverseビュー(FetchXML、列、ソート)。Dataverseでビューを編集した後にリフレッシュしてください。
- EntityMetadata — 低レベルのフレームワークコードで使用される生のDataverseエンティティメタデータ。TableMetadataと同じソースですが、形が異なります — 通常は一緒にリセットされます。
- StringLocalizer — すべてのローカライズされた文字列 — Dataverseのテーブル/カラムラベル、ウェブリソース、フォルダ内のJSONファイル。ローカリゼーションソースを編集した後にリフレッシュしてください。
- UserPrivileges — ユーザーごとのセキュリティ権限(どの役割がどの権限を与えるか)を解決しました。ユーザーの役割割り当てを変更した後にリフレッシュしてください。
- TablePermissions — ユーザーごと、テーブルごとのCRUD権限はテーブル権限ハンドラーチェーンを通じて解決されました。主にSystemUsersのUserPrivilegesから派生しています。
- PrivilegeMetadata — Dataverse特権テーブルからの組織全体の権限定義。ほとんど変更はなく、Dataverseプラットフォームのアップデートのみが新しいエントリーを導入します。
- OrganizationFileSettings — 組織レベルのファイルアップロード設定(最大サイズ、許可される拡張子数)。Dataverseでこれらの変更をした後にリフレッシュしてください。
- Currency — 組織全体の取引通貨スナップショットと組織の基本通貨。管理者がDataverseで通貨を追加・更新した後にリフレッシュしてください。
- EmailSender — 送信者レコードの解決済み(設定済み送信者アドレスをDataverseエンティティ参照に検索)。
StringLocalizerの再構築が遅いのが一番です
StringLocalizerのキャッシュをクリアすると、Dataverseテーブルのメタデータ+ウェブリソース+フォルダファイルがすべて歩き、メモリ内の辞書を再構築します。実際の環境に対して20〜30秒の時間がかかると覚悟してください。アトミックリビルドは、リーダーがリビルド中ずっと前の値を見続けることを保証します。キャッシュが空になる期間はありません。
自分のキャッシュを追加する
IClearableCacheを実装し、コンクリートサービスとして、そしてIClearableCacheとして登録してください。サイト管理者のページは自動的に取得し、他のものとアルファベット順にレンダリングします。Nameプロパティはパブリック識別子であり、キャッシュごとに表示されるものです。
public class MyCustomCache : IClearableCache
{
public string Name => "MyCustomCache";
public Task ClearAsync(CancellationToken cancellationToken)
{
// インメモリ状態を解除したり、再埋め込みしたりします。
return Task.CompletedTask;
}
}
// Program.cs
builder.Services.AddSingleton<MyCustomCache>();
builder.Services.AddSingleton<IClearableCache>(sp => sp.GetRequiredService<MyCustomCache>());
局所的な説明
サイト管理者ページでは、ローカリザーで app.cache-descriptions.<Name> を調べてボタンの横にある説明文を表示します。ポータルの app.en.json (および他の言語ファイル)でその名前空間の下にエントリを追加してください。登録された説明がないページはボタンだけを滑らかにレンダリングします。
{
"app": {
"cache-descriptions": {
"MyCustomCache": "このキャッシュには何が入っていて、いつリセットすべきかも知りたいです。"
}
}
}
すべてクリア vs. キャッシュごとの比較
Clear Allは登録済みのすべてのキャッシュの ClearAsync を並列に実行し、応答としてキャッシュごとの結果(成功/失敗/経過ms)を報告します。キャッシュごとにボタンは1つのキャッシュに対して同じ ClearAsync を発動させるため、例えばDataverseビューを1つ編集した後に1つだけ削除する場合に便利です。
API参照
キャッシュクリアAPIは IPowerPortalsProServiceに残り、各キャッシュの ClearAsync を並列に動かす基盤となるオーケストレーションは、 ICacheManager上で生き続けます。インターフェースは以下にまとめます。
IClearableCache Interface
性質
名称 | 種類 | デフォルト | 概要 |
|---|---|---|---|
Name | string | テレメトリーやUIフィードバックのための短く安定した名称(例:「 |
Name方法
名称 | パラメータ | 種類 | 概要 |
|---|---|---|---|
ClearAsync | CancellationToken cancellationToken | Task | キャッシュの中身を消去します。事前読み込みデータを維持するキャッシュの場合 (例: |
ClearAsyncICacheManager Interface
方法
名称 | パラメータ | 種類 | 概要 |
|---|---|---|---|
ClearAllAsync | CancellationToken cancellationToken | Task<IReadOnlyList<CacheClearResult>> | 登録済みのすべての Services.IClearableCache を並行してクリアし、返却します キャッシュごとのレポートです。失敗したキャッシュは他のキャッシュをブロックするのではなく、そのキャッシュの入りをブロックします。 レポートには |
ClearAsync | string name CancellationToken cancellationToken | Task<CacheClearResult> | 名前のあるキャッシュを1つクリアします。登録されていない場合は返品 null キャッシュは name と一致します(大文字を区別しません)。故障はラップされます 投げるのではなく結果に反映され、 Threading.CancellationToken)を一致させました。 |
GetCacheNames | IReadOnlyList<string> | 登録されたすべての Services.IClearableCacheの名前を返します。 キャッシュごとにクリアボタンをレンダリングしたい管理者UI向けに。 |
ClearAllAsyncServices.IClearableCache を並行してクリアし、返却します キャッシュごとのレポートです。失敗したキャッシュは他のキャッシュをブロックするのではなく、そのキャッシュの入りをブロックします。 レポートには ClearAsyncCancellationToken cancellationToken
null キャッシュは name と一致します(大文字を区別しません)。故障はラップされます 投げるのではなく結果に反映され、 Threading.CancellationToken)を一致させました。GetCacheNamesServices.IClearableCacheの名前を返します。 キャッシュごとにクリアボタンをレンダリングしたい管理者UI向けに。