サイト管理者
PowerPortalsProは、SystemUser支援の管理者がホストを再起動せずにサーバー側のキャッシュをクリアできるSite Adminページを提供しています。フレームワークはキャッシュクリアAPI(IPowerPortalsProService.ClearAllCachesAsync / ClearCacheAsync)を提供します。ポータルはページ自体、ロールゲート、ナビリンクを提供します。
配線
接続すべきものは3つあります:ロールクレームトランス、ページ自体、そしてナビエントリーです。ポータルテンプレート(Auto、WebAssembly、Serverのインタラクティブオプションpowerportalspro-csharp)は、3つすべてを箱から出荷します。下のスニペットはテンプレートが発信する内容を反映しているため、テンプレートから生成されていないポータルに持ち上げることができます。
1. どのDataverseロールが管理者権限を与えるかを設定する
SystemAdminClaimsTransformer組み込みのSystem Administrator DataverseセキュリティロールまたはSecurityOptions.SystemAdminRoleName名のカスタムユーザーのいずれかを持つ内部ユーザーに合成されたSystemAdminロールクレームを刻み込みます。これはフレームワークの管理者エンドポイントがチェックする同じルールです。組み込みロールは常に管理者として扱われます。設定されたロールは任意で、その上にレイヤーが加わります。UIをゲートに、エンドポイントが尋ねる質問にまさに答える[AuthorizeSystemAdmin]と<SystemAdminView>(React、useIsSystemAdmin()、<SystemAdminView>)でゲートし、カスタムDataverseロールに管理者権限を与えられます。名前だけでゲートしないでください。[Authorize(Roles = "SystemAdmin")]と<AuthorizeView Roles="SystemAdmin">は、誰かが名前を付けたポータルロールやウェブロールが持つ非タイプドロールの主張と一致しますSystemAdmin。
// appsettings.json — 任意です。組み込みの「システム管理者」の所有者
// Dataverseの役割は常にポータル管理者として扱われます。SystemAdminRoleNameレイヤー
// さらにDataverseの役割も加わりました。
{
"Security": {
"SystemAdminRoleName": "ポータル管理者"
}
}
// Program.cs
builder.Services.Configure<SecurityOptions>(
builder.Configuration.GetSection("Security"));
builder.Services.AddSingleton<IClaimsTransformation, SystemAdminClaimsTransformer>();
2. サイト管理者ページを追加する
[AuthorizeSystemAdmin]属性はAuthorizeRouteViewによって尊重され、内側の<SystemAdminView>はホストがルーターを交換した場合に備えた防御深層(defense in depth)です。両者とも、上記の役割のいずれかを持つ内部(systemuser)セッションのみを許可します。ページ全体(Clear Allボタン、キャッシュごとのローカライズされた説明付きリスト、トーストフィードバックを含む)はテンプレートのSiteAdmin.razorに収まります。
@attribute [Route("admin/site-admin")]
@attribute [AuthorizeSystemAdmin]
@inject IPowerPortalsProService _powerPortalsProService
@inject IToastService _toastService
<SystemAdminView>
<Authorized>
</Authorized>
</SystemAdminView>
3. ナビゲーションに表面化
管理者ナビグループを <SystemAdminView> でラップして、非管理者が追跡できないリンクを見ないようにしましょう。リンクターゲットはページが登録するルートです。
<SystemAdminView>
<Authorized>
<FluentNavCategory Title="管理" IconRest="@(new Size20.WrenchSettings())">
<FluentNavItem Href="admin/site-admin">
<FluentIcon Value="@(new Size20.LauncherSettings())" />
サイト管理者
</FluentNavItem>
</FluentNavCategory>
</Authorized>
</SystemAdminView>
キャッシュされるもの
フレームワークは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向けに。