拡張サーバースクリプトの適用条件
拡張サーバースクリプトは、JSON に書いた SiteIdList・Controllers・Actions などの条件で、どのリクエストに適用するかを絞り込めます。絞り込み自体は正しく動きますが、次の 2 点に注意が必要です。
Controllers・Actionsは小文字で書きます。大文字を含めるとエラーにはならず、ただ一致しなくなります。- 1 つのリストに肯定指定(
"create")と除外指定("-delete")を混ぜないでください。混ぜると肯定指定が効かなくなります。
ファイルの置き方
拡張サーバースクリプトは App_Data/Parameters/ExtendedServerScripts/ の *.json から読み込まれます。サブフォルダの中も再帰的に読み込まれます。xxx.json と同じ場所に xxx.json.js があれば、その内容が Body として使われます(JSON の Body は上書きされます。Initializer.cs#L758-L789)。
{
"Name": "sample-script",
"SiteIdList": [12345],
"Controllers": ["items"],
"Actions": ["create", "update"],
"BeforeCreate": true,
"BeforeUpdate": true,
"Body": "context.Log('作成・更新のときだけ実行');"
}JSON に書ける項目は、絞り込み用の共通項目(ExtendedBase)と、サーバースクリプトの項目です(ExtendedBase.cs、ExtendedServerScript.cs)。
| 分類 | 項目 |
|---|---|
| 絞り込み | SpecifyByName・Name、DeptIdList、GroupIdList、UserIdList、SiteIdList、IdList、Controllers、Actions、Disabled |
| 実行条件 | WhenloadingSiteSettings・WhenViewProcessing・WhenloadingRecord・BeforeFormula・AfterFormula・BeforeCreate・AfterCreate・BeforeUpdate・AfterUpdate・BeforeDelete・BeforeBulkDelete・AfterDelete・AfterBulkDelete・BeforeOpeningPage・BeforeOpeningRow |
| 実行方法 | Shared、Functionalize、TryCatch、Body |
タイムアウトは個別に指定できない
ExtendedServerScript には TimeOut がありません。サイトのスクリプトに変換するときもタイムアウトは設定されないため(SiteSettings.cs#L6212-L6238)、拡張サーバースクリプトには Script.json の ServerScriptTimeOut が使われます。同じ条件のサイトのスクリプトに長いタイムアウトがあれば、結合されてそちらが適用されます(タイムアウト)。
絞り込みの流れ
サーバースクリプトの一覧を作るとき(SiteSettings.GetServerScripts)に、ExtensionWhere で現在のリクエストに合う拡張サーバースクリプトだけが選ばれ、サイトのスクリプトの前に並べられます(サーバースクリプトの内部構造)。その後、実行のたびに実行条件(BeforeCreate など)で絞り込まれます。
図を読み込み中…
比較に使う値は、SiteIdList はサイト設定のサイト ID、IdList は context.Id、Controllers・Actions は context.Controller・context.Action です(ExtensionUtilities.cs#L182-L231)。context.Controller・context.Action はルートの値を ToLower() したものです(Context.cs#L289-L290)。どんな値になるかは context.Action を参照してください。
MeetConditions の評価ルール
各リストの判定は MeetConditions で、次の 3 つのどれかが真なら一致とみなします(ExtensionUtilities.cs#L236-L291)。
| 判定 | 真になる条件 |
|---|---|
| 条件なし | リストが空(null を含む)、または比べる値が空 |
| 肯定指定 | リストのどれかが値と完全に一致する(== による比較で、大文字・小文字を区別する) |
| 除外指定 | - で始まる要素があり、そのすべてが -値 と一致しない |
小文字で書く
context.Controller・context.Action は小文字なので、肯定指定も除外指定も小文字で書かないと一致しません。
| 設定値 | リクエストの値 | 結果 |
|---|---|---|
"items" | items | 一致する |
"Items" | items | 一致しない(ほかに条件がなければ適用されない) |
"-items" | items | 除外される |
"-Items" | items | 除外されない(-Items は -items と一致しないので、除外指定としては「通過」になる) |
肯定指定と除外指定を混ぜない
3 つの判定は OR でつながっているため、1 つのリストに両方を書くと、除外指定が真になった時点で肯定指定に関係なく一致します。
Actions | リクエストの action | 肯定指定 | 除外指定 | 結果 |
|---|---|---|---|---|
["create", "-delete"] | create | 真 | 真 | 適用 |
["create", "-delete"] | update | 偽 | 真 | 適用(create だけのつもりでも適用される) |
["create", "-delete"] | delete | 偽 | 偽 | 適用しない |
["-delete", "-bulkdelete"] | update | 偽 | 真 | 適用 |
["-delete", "-bulkdelete"] | delete | 偽 | 偽 | 適用しない |
特定のアクションだけで動かしたいときは肯定指定だけ(["create", "update"])、特定のアクションだけ外したいときは除外指定だけ(["-delete", "-bulkdelete"])で書きます。この評価ルールは拡張 SQL・拡張スクリプト・拡張スタイルなど、ExtensionWhere を使う拡張機能すべてで同じです。
{
"Name": "exclude-delete",
"SiteIdList": [12345],
"Actions": ["-delete", "-bulkdelete"],
"BeforeOpeningPage": true,
"Body": "context.Log('削除以外で実行');"
}画面と API でコントローラ名が同じになることがある
API 用の Controllers/Api/ItemsController は [Route("api/[controller]")] の属性ルーティングで、[controller] はクラス名から Items になります(Api/ItemsController.cs#L20-L22)。そのため Controllers: ["items"] は画面からの操作と API からの操作の両方に一致します。画面だけ・API だけに絞りたい場合は、Actions やスクリプト内の判定(context.ApiRequestBody など)を組み合わせてください。
通常のサーバースクリプトとの違い
サイト設定から登録するサーバースクリプト(ServerScript クラス)には、Controllers・Actions などの絞り込み項目がありません(ServerScript.cs#L7-L35)。実行条件に合えば、どの画面・操作でも実行されます。操作で分けたい場合は、スクリプトの中で context.Action を見て分岐します。
| 通常のサーバースクリプト | 拡張サーバースクリプト | |
|---|---|---|
| 登録場所 | サイト設定(テーブルごと) | App_Data/Parameters/ExtendedServerScripts/ |
| コントローラ・アクション・ユーザーなどでの絞り込み | なし(スクリプト内で判定する) | JSON の条件で絞り込める |
| タイムアウトの個別指定 | できる(ServerScriptTimeOutChangeable が true のとき) | できない |
| 実行順 | 拡張サーバースクリプトの後 | サイトのスクリプトより前 |
絞り込み結果のキャッシュ
絞り込んだ結果は SiteSettings のインスタンスにキャッシュされます。サイト設定はリクエストごとに読み直されるので、前のリクエストのコントローラ・アクションで絞り込んだ結果が次のリクエストに持ち越されることはありません。