Skip to content

1.5.7.0 の変更点 ​

第8版作成 最終更新 (日本時間)
確認バージョン1.5.7.0

リリース日: 2026年8月12日。1.5.6.1 からの変更です。機能追加・仕様変更と不具合修正を分けて記載します。

機能追加・仕様変更 ​

  • その他 — マルチテナント機能が加わった。
  • 運用・設定 — キューイング機能にレコードのインポート機能が加わった。
  • 利用者・権限 — SAML連携で、ユーザの拡張項目を取り込む機能が加わった。
  • その他 — サーバのウォームアップ機能が加わった。
  • 実行環境・DB — ASP.NET Core Data Protection キーをKVSに保存できるようになった。
  • 運用・設定 — バイナリデータを Azure Blob に保存できるようになった。
  • API・拡張 — スクリプト、スタイル、HTMLのドラフト出力を利用できるようになった。
  • その他 — リッチテキストエディタのライブラリを更新した。
  • 運用・設定 — 信頼するプロキシ認証を有効化した場合、Security.jsonのKnownNetworksまたはKnownProxiesを必須とするよう変更に関する仕様を更新した。
  • 利用者・権限 — ログイン画面右上のPleasanter.netリンクを取り除いた。

不具合修正 ​

  • 運用・設定 — Mail.jsonのSendGrid.ApiKeyの設定が適用されない不具合を修正。
  • その他 — BackgroundServerScriptがDeploymentEnvironmentを参照せず待機系サーバでも実行される不具合を修正。
  • データ入出力 — CSP違反レポート有効時に syslogs ファイル出力が停止する不具合を修正。
  • 利用者・権限 — BackgroundServerScriptが実行ユーザーのタイムゾーンを反映しない不具合を修正。
  • API・拡張 — サーバスクリプトのitems.GetSiteで取得したサイトのapiModelでCreate関数を実行するとエラーが発生する不具合を修正。
  • 通知・メール — APIによるメール送信時にエラー原因が特定しにくい不具合を修正。
  • その他 — サブディレクトリ構成でFormのサンクスメッセージが表示できない不具合を修正。

実装を読む ​

1.5.6.1 との差分です。新規追加ファイルは 60 本以上あります。

分類追加された主なもの概要ライセンス
マルチテナント管理 APIapi/tenants 系エンドポイントテナントの払い出し・停止・削除を API 化必要(トライアル不可)
バイナリストレージAzureBlob プロバイダ添付ファイルを Blob Storage に直接置ける不要
起動ウォームアップWarmupGateMiddleware初期化完了までリクエストを受け付けない不要
分散ロックDistributedLock複数インスタンスでの起動処理の競合を防ぐ不要
ヘルスチェックウォームアップ状態のチェック初期化中はロードバランサから外れる不要
データ保護キーRedis への保存インスタンス間で鍵を共有できる不要
バックグラウンドジョブImportJobHandlerインポートをジョブとして裏で流せる必要(Queue)
一覧のエラー処理GridDataTimeoutException一覧のタイムアウトを識別して返す不要
下書き出力DraftOutputModeスタイル・スクリプト・HTML を下書き時だけ出し分け不要

マルチテナント管理 API ​

Implem.Pleasanter/Controllers/Api/TenantsController.cs が新設され、テナントを API で操作できるようになりました(ソース)。

メソッドパス用途
POSTapi/tenants/Getテナント一覧の取得
POSTapi/tenants/Createテナントと初期ユーザーの作成
POSTapi/tenants/{id}/Suspendテナントの利用停止
POSTapi/tenants/{id}/Resume停止したテナントの再開
POSTapi/tenants/{id}/Deleteテナントの削除依頼

前提条件 ​

すべてのメソッドで、Parameters.AllowMultiTenants()(マルチテナントのライセンス)と context.HasPrivilege(Security.json の PrivilegedUsers に含まれる特権ユーザー)がチェックされます。

トライアルライセンスでは使えない

他の Allow*() は TrialLicense?.Check() ?? ... の形で、トライアルライセンスがあればオプションを見ずに通ります。AllowMultiTenants() だけはこの形をとっていないため、トライアル環境ではマルチテナント API を試せません。

csharp
public static bool AllowQueue()
{
    return TrialLicense?.Check() ?? License.Check() && HasQueue();
}

public static bool AllowMultiTenants()
{
    return License.Check() && HasMultiTenants();   // トライアルのフォールバックなし
}

ライセンスは認証にも影響します。1.5.7.0 で Context に次の判定が追加されました。

csharp
if (!Parameters.MultiTenant.IsProtectedTenant(TenantId) && !Parameters.AllowMultiTenants())
{
    Authenticated = false;
}

MultiTenant.json の DefaultTenantId で指定した保護テナント以外は、マルチテナントのライセンスがないとログインできません。ライセンスなしの環境で 2 つ目以降のテナントを作っていた場合は、1.5.7.0 へ上げる前に確認してください。

テナントの作成 ​

リクエストボディは CreateTenantApiModel にデシリアライズされます(ソース)。

json
{
  "ApiKey": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "TenantName": "サンプル商事",
  "Title": "サンプル商事 プリザンター",
  "LoginId": "sample-admin",
  "Name": "サンプル管理者",
  "NotifyMailAddress": "admin@example.com",
  "Language": "ja"
}
  • TenantName・LoginId・Name・NotifyMailAddress は必須で、未指定だと PleaseInputData エラーになります。NotifyMailAddress はメールアドレスの形式もチェックされます。
  • テナントと同時に、LoginId / Name のテナント管理者(TenantManager = true)が 1 人作られます。パスワードは Service.json の DefaultPassword です。Security.json の PasswordExpirationPeriod が有効なら有効期限も設定されます。
  • 作成後、NotifyMailAddress 宛に案内メールが送られます。送信元は Mail.json の SupportFrom で、未設定だとメールは送られません(テナントは作成されます)。本文テンプレートは App_Data/Displays/TenantCreatedMailBody.json にあり、多言語定義と同じ仕組みで差し替えられます。

停止と再開 ​

Suspend は Tenants テーブルの ContractDeadline(契約期限)に日付を書き込むだけの実装です。SuspendDate を省略すると当日、将来日を指定すれば予約停止になります。Resume は ContractDeadline を null に戻します。期限切れでログインを止める判定も 1.5.7.0 で追加されており、保護テナントは対象外です。

削除は 2 段階 ​

Delete は物理削除ではなく、1.5.7.0 で追加された Tenants.DeleteRequestTime 列に削除依頼日時を書き込むだけです。実際の削除はバックグラウンドサービスが行います。

図を読み込み中…

json
{
    "DeleteTenant": true,
    "DeleteTenantTime": [ "04:00" ],
    "DeleteTenantRetentionPeriod": 30,
    "DeleteTenantChunkSize": 1000,
    "DeleteTenantBinariesChunkSize": 10
}

ChunkSize 系は、テナント配下のレコードや添付ファイルを分割しながら削除して DB の負荷を抑えるための設定です。

WARNING

1.5.8.0 で DeleteTenant の既定値が false に変わりました。1.5.8.0 の「既定値の変更(DeleteTenant)」を参照してください。

保護テナント ​

新しいパラメータファイル MultiTenant.json が追加されました。

json
{
    "DefaultTenantId": 1
}

DefaultTenantId に指定したテナントは Suspend / Resume / Delete を受け付けず、バックグラウンドの物理削除でもスキップされます(SysLogs に警告が残ります)。API の操作ミスで基盤テナントごと消える事故を防ぐためのガードです。

添付ファイルを Azure Blob Storage に置ける ​

添付ファイルの格納方式にインターフェース(IBinaryStorageProvider)が切られ、プロバイダを差し替えられる構造になりました(ソース)。

csharp
public static IBinaryStorageProvider Create(string provider)
{
    return provider switch
    {
        BinaryStorageProviderNames.LocalFolder => new LocalFolderBinaryStorageProvider(),
        BinaryStorageProviderNames.Local => new LocalFolderBinaryStorageProvider(),
        BinaryStorageProviderNames.AzureBlob => new AzureBlobBinaryStorageProvider(),
        _ => null
    };
}
  • Rds の場合はプロバイダが null になり、従来どおり Binaries.Bin 列を読み書きします。
  • IBinaryStorageProvider は Upload / Download / OpenRead / Delete / Exists / LastWriteTime を同期版と Async 版で定義しています。独自ストレージに対応させるには、このインターフェースを実装してファクトリに 1 行足します。
  • BinaryStorage.json に AzureBlobStorageAccountUri と AzureBlobContainerName が追加されました。どちらも環境変数で上書きできます。
  • 認証には DefaultAzureCredential を使うため、接続文字列やアカウントキーを設定ファイルに書く必要はありません。App Service や Container Apps のマネージド ID にストレージの BLOB データ共同作成者ロールを付与すれば動きます。ローカル開発時は Azure CLI のログイン情報が使われます。
  • 添付ファイルは Attachments/{Guid} というオブジェクト名で保存されます。
  • サーキットブレーカーを備えています。接続・認証に失敗すると 30 秒 → 2 分 → 10 分と段階的に遮断時間が延び、遮断中は即座に IOException を返します。1 回でも成功すれば失敗カウントはリセットされます。失敗内容は SysLogs に記録されます。

一時ファイルが外部ストレージへ移送されるようになった ​

ロードバランサ配下で、アップロードとレコード保存が別インスタンスに振り分けられる問題を避けるため、TemporaryBinaryStorageProvider を Rds にして一時ファイルだけ DB に置く運用があります。1.5.6.0 以前はこの構成だと保存後もファイルが Binaries.Bin に残り続けていましたが、1.5.7.0 では保存時に外部ストレージへ移送されます(ソース)。移送に失敗した場合は SysLogs に記録して例外を投げるため、DB 側だけ NULL になって実体を見失うことはありません。

起動ウォームアップ ​

起動時の初期化(テナント・拡張機能・ユーザー・アイテム・マイグレーション・ステータス・通知・サイト情報)がホステッドサービス ApplicationWarmupHostedService に切り出され、完了するまでリクエストをゲートで止めるようになりました(ソース)。状態は WarmupStatus(NotStarted / InProgress / Completed / Failed / Canceled / TimedOut)で管理されます。

Completed 以外のときは、WarmupGateMiddleware がリクエストの種類ごとに応答を振り分けます(ソース)。

図を読み込み中…

  • 静的ファイルとエラーページを通すのは、リダイレクト先の /errors/warmup 自体を表示できるようにするためです。
  • IIS の Application Initialization からのリクエストだけは、ウォームアップが終わるまで待ってから 200 を返します。
  • 初期化に失敗した場合はアプリケーション自体が停止します。

タイムアウトと停止までの猶予は BackgroundService.json で調整できます。サイト数やユーザー数が多い環境では、既定の 180 秒で足りるか実測して確認してください。

json
{
    "WarmupTimeoutSeconds": 180,
    "WarmupFailureShutdownDelaySeconds": 60
}

分散ロック ​

複数インスタンスを同時に起動したときに DB のマイグレーションが並行して走らないよう、DistributedLock が追加されました(ソース)。Redis などではなく DB のロック機構を使うため、追加のインフラは不要です。

DBMS使用する仕組み
SQL Serversp_getapplock(@LockOwner = 'Session')
PostgreSQLpg_advisory_lock() + lock_timeout
MySQLget_lock()
その他従来どおり排他制御を行わずに処理を続ける

起動時のマイグレーションは startup-migrations という名前のロックで保護され、ロックを取れなかったインスタンスは先行インスタンスの完了を待ってから次に進みます。

ヘルスチェック ​

/healthz は以前からありますが、1.5.7.0 で次の点が変わりました。

  • 登録処理が Startup.cs から HealthCheckExtensions.cs に切り出された
  • ウォームアップ状態を返すチェック(warmup)が追加された(ソース)
  • Security.json の HealthCheck.Enabled の既定値が false から true に変わった
WarmupStatus結果HTTP
CompletedHealthy200
NotStarted / InProgressDegraded503
Failed / Canceled / TimedOutUnhealthy503

ウォームアップ中は 503 になるため、ロードバランサの振り分け対象から自動的に外れます。

diff
  "HealthCheck": {
-     "Enabled": false,
+     "Enabled": true,
      "EnableDatabaseCheck": false,
      "HealthQuery": null,
      "RequireHosts": null,
      "EnableDetailedResponse": false
  },

WARNING

/healthz は既定で応答するようになりました。RequireHosts が null のままだとホスト制限なしで公開されるため、監視元を限定したい場合は設定してください。

データ保護キーを Redis に置ける ​

複数インスタンスで動かす場合、ASP.NET Core のデータ保護キーを共有しないと Cookie の復号に失敗してログインが維持できません。従来の Azure Blob Storage に加え、Redis が選べるようになりました(ソース)。

diff
  "AspNetCoreDataProtection": {
      "BlobContainerUri": null,
      "KeyIdentifier": null,
      "KeyFileName": "Keys.xml",
-     "XmlAesKey": null
+     "XmlAesKey": null,
+     "KeyValueStoreConnectionString": null,
+     "KeyValueStoreKeyName": null
  },

KeyValueStoreConnectionString を指定すると PersistKeysToStackExchangeRedis() が使われます。優先順位は Blob(BlobContainerUri と KeyIdentifier の両方が設定されている場合)→ Redis → ローカル(既定)です。セッションの共有(Kvs.json の ConnectionStringForSession)で Redis を使っている環境なら、同じインスタンスにキーも置けます。

バックグラウンドジョブでインポートを実行できる ​

バックグラウンドジョブは以前からエクスポートに対応していましたが、インポート(BackgroundJobTypes.Import)が追加されました。ImportJobHandler がジョブに紐づく CSV を読み込み、通常のインポートと同じ処理を裏で実行します。結果は ImportResultData にまとめられ、件数やエラー内容がジョブの結果として残ります。

json
{
    "BackgroundQueue": false,
    "BackgroundJobDispatcherInterval": 60,
    "BackgroundJobTimeout": 3600,
    "FallbackLanguage": "ja",
    "RecoverAction": "Failed",
    "OutputFilePath": null,
    "InputFilePath": null
}

BackgroundQueue を true にし、InputFilePath に読み込み元のディレクトリを指定して使います。

WARNING

バックグラウンドジョブ機能そのものに上位ライセンス(Queue オプション)が必要です。BackgroundQueue を true にしても、ライセンスがなければキューは有効になりません。判定は AllowQueue() なのでトライアルライセンスでも有効になります。ライセンスの条件は 1.5.6.0 から変わっていません。

一覧のタイムアウトを識別できる ​

一覧のデータ取得で例外が起きたとき、従来は原因によらず「ソートできません」になっていましたが、1.5.7.0 では 3 種類に分かれます(ソース)。

例外条件ビュー
GridDataTimeoutExceptionDB のタイムアウト(判定は DBMS ごと。SQL Server は SqlException.Number == -2)リセットしない
CanNotGridSortExceptionその他の DbExceptionリセットしてソートエラーを返す
GridDataExceptionその他の例外—

タイムアウトのときはビューがリセットされないため、重いクエリでタイムアウトしてもフィルタ条件が残ります。

スタイル・スクリプト・HTML の下書き出力 ​

管理画面のスタイル・スクリプト・HTML に DraftOutputMode と DraftKey が追加されました。本番サイトで、一般利用者には見せずに新しいスクリプトを検証するための機能です。

DraftOutputMode挙動
0(既定)常に出力する
1下書き時のみ出力する
2下書き時は出力しない

下書きかどうかは、クエリパラメータ Draft の値が DraftKey と一致するかで判定されます(ソース)。DraftKey を指定しなければ 1 が使われるため、?Draft=1 で切り替わります。

text
/items/123?Draft=newfeature

この例では、DraftKey に newfeature を設定したスクリプト(DraftOutputMode が 1)がこの URL のときだけ出力されます。DraftOutputMode を 2 にしておけば、既存のスクリプトを下書き確認時だけ止められます。

WARNING

DraftKey は URL に平文で載るため、秘匿情報ではありません。

調査元 ​

変更履歴

第8版1.5系の変更記事に設定例と実装の詳細を追加
第7版1.5.7.0 の変更点と4項目の比較データを追加
第6版1.5.7.0の変更点を独立させ旧記事を版別に移行
第5版「バージョン別の追加機能(1.5.7.0 / 1.5.8.0)」にスクリーンショットを追加
第4版「機能の仕様と使いこなし」「スクリプト」「サーバースクリプト」に対応バージョンを表示
第3版「機能の仕様と使いこなし」を 1.5.8.1 のソースで検証して修正
第2版記事のファイル名に並び順の番号を付け、元記事リンクを frontmatter の sources に移行
第1版「機能の仕様と使いこなし」セクションの記事を追加