FileGrid
FileGridコンポーネントは、Dataverseレコードを管理するための専門的なグリッドで、主な内容は単一のファイルカラムです。ドラッグ&ドロップアップロード、行ごとのプレビュー・ダウンロードアイコン、そして読み込まれたすべてのファイルの一括ダウンロードを、MainGridとレイヤーをラップし、レイヤーを付けています。また、Dataverseの環境全体のブロック拡張リストや各カラムサイズ制限も尊重し、スコープ内であればパイプラインのMainContext/RecordContextセーブにも参加します。
例 ppp_fileデモテーブル上のファイルアップロードを管理します(ファイル自体はppp_data列に位置しています)。グリッドは保存とリフレッシュボタンで囲むMainContextで、落としたファイルはDataverseを押さずにメモリにキューイングし、デモのOnBeforeSaveは実際のセーブや模擬リセットの状態をキャンセルします。PDFや画像をグリッドにドラッグし、複数の行を選択して「全部ダウンロード」をクリックし(zipに注目)、1行のプレビューアイコンをクリックしてみてください。アップロードボタンを見るにはログインが必要です。所有していないファイルは閲覧可能ですが、読み取り専用です。
Reactの例
ブレイザーの例
ファイルのアップロード、編集、削除はログインが必要です。所有していない記録は閲覧可能ですが、読み取り専用です。
React TypeScript
Razor
基本的な使用法
グリッドが管理すべきテーブルとファイル列の論理名を指定します。アップロード、ファイルの置換、すべてダウンロード、削除ボタンが自動的に表示されます。ファイルはグリッド上に落とすことも可能です。 <Buttons> レンダリングフラグメントを渡して、内蔵ツールの隣に自分のツールバーボタンを追加してください。これは同じパターン MainGrid で、 SubGrid サポートも同じです。
React
<FileGrid tableName="ppp_file"
fileColumn="ppp_data" />
Blazor
<FileGrid TableName="ppp_file"
FileColumn="ppp_data" />
自動ファイルカラム注入
アクティブなビューのFetchXMLや列リストに FileColumnが含まれていない場合、グリッドはそれをクローンコピーに移植し、ファイル名、タイプアイコン、行ごとのプレビュー/ダウンロードアイコンが常にレンダリングされます — どのビューを選んでも。キャッシュ共有ビューインスタンスはそのまま残され、他のグリッドには影響を受けません。
React
{/* Even if the saved view doesn't include ppp_data in its column list, the
FileGrid adds it automatically so the filename and action icons are always visible. */}
<FileGrid tableName="ppp_file"
fileColumn="ppp_data"
defaultViewId="..."
viewIds={viewIds} />
Blazor
<!-- Even if the saved view doesn't include ppp_data in its column list, the
FileGrid adds it automatically so the filename and action icons are always visible. -->
<FileGrid TableName="ppp_file"
FileColumn="ppp_data"
DefaultViewId="@(new Guid("..."))"
ViewIds="_viewIds" />
最大ファイルサイズ
MaxFileSizeBytesを使ってアップロードファイルのサイズを制限しましょう。グリッドは列のMaxSizeInKBメタデータ と環境 のmaxuploadfilesize設定の小さい方に値を圧縮するため、サーバー側で拒否されたファイルはそもそもキューに入れられません。実効上限を超えるファイルは、Dataverseに送られる前にダイアログを生成します。
React
<FileGrid tableName="ppp_file"
fileColumn="ppp_data"
maxFileSizeBytes={10485760} />
Blazor
<FileGrid TableName="ppp_file"
FileColumn="ppp_data"
MaxFileSizeBytes="10485760" />
許可された延長
アップロードを拡張のホワイトリストに制限するために AllowedExtensions パスしてください。拒否されたファイルは、どの拡張子が受け入れられるかを説明するダイアログを表示します。設定されていない場合、任意の拡張が許可されます(下記の環境ブロックリストに従います)。
React
<FileGrid tableName="ppp_file"
fileColumn="ppp_data"
allowedExtensions={['.pdf', '.docx', '.txt']} />
Blazor
<FileGrid TableName="ppp_file"
FileColumn="ppp_data"
AllowedExtensions="@(new[] { ".pdf", ".docx", ".txt" })" />
環境ブロックリスト
Dataverse環境は、呼び出し元に関係なく特定の拡張(SVG、EXE、BAT、JSなど)を拒否する blockedattachments リストを管理します。 FileGrid は IPowerPortalsProService.GetEnvironmentFileSettingsAsync() コールを通じてinit時にこのリストを読み取り、1時間キャッシュし、サーバー側の故障ではなくフレンドリーメッセージでクライアント側の一致ファイルを拒否します。環境ブロックリストは常にこの AllowedExtensions に勝ちます — カラムの許可リストは環境レベルのブロックを上書きできません。
SVGをアップロードできない?
Dataverse環境はデフォルトで svg をブロックします。なぜならSVGは組み込みスクリプトを搭載できるからです。SVGのアップロードが必要な場合は、Power Platform管理センターの「 添付ファイル拡張子のブロック 設定」から削除してください。このグリッドが1時間以内に変更を検出します。
許可ゲート
アップロードボタンとドロップゾーンの有効化は、現在のポータルユーザーがターゲットテーブルに対して Create 権限を持っているかどうかを尊重します。作成がない場合はアップロードボタンが隠され、グリッド上にファイルをドラッグするのはノーオペレーション(操作禁止)です。サーバー側の強制は依然としてバックアップとして実行されます。許可は ITablePermissionCache で解決されるため、カスタム ITableRecordPermissionHandler 実装も同じゲートロジックに入力されます。また、アップロードボタンは1行以上選択すると自動で非表示になり、ツールバーをきれいに保ちます。
行ごとのプレビュー&ダウンロード
ファイル列は [type-icon] filename [eye] [download]のようにレンダリングされます。プレビューアイコンは FilePreviewDialog を開きます — 各ファイル形式の詳細は下記の プレビュー レンダリングをご覧ください。ダウンロードアイコンは FileDownload JSInteropコンポーネントを通じてファイルをストリーミングします。どちらのアイコンもグリッドごとに、 AllowPreviewForFileColumns や AllowDownloadForFileColumnsでオフにできます。
React
{/* Both icons default to true. Turn either off per-grid. */}
<FileGrid tableName="ppp_file"
fileColumn="ppp_data"
allowPreviewForFileColumns
allowDownloadForFileColumns />
Blazor
<!-- Both icons default to true. Turn either off per-grid. -->
<FileGrid TableName="ppp_file"
FileColumn="ppp_data"
AllowPreviewForFileColumns="true"
AllowDownloadForFileColumns="true" />
プレビューアイコンはダイアログでレンダリング可能なファイルタイプにのみ表示されます。サポートされていない拡張子は壊れたaffordanceを表示せず、アイコンをスキップします。両方のアクションアイコンは、保留中の作成行(まだDataverseに保存されていないレコード)に隠されています。
プレビューレンダリング
FilePreviewDialogはファイルの拡張子に基づいてレンダラーを選択します:
画像( png、jpg、jpeg、gif、bmp、webp、svg)—base64のデータURLとインライン <img> 。70 vhに制限されているので、非常に高い画像はダイアログ内でスクロール可能です。
PDF — <iframe> にブロブURLとして読み込まれ、ブラウザの内蔵ビューアが複数ページのスクロール、ズーム、検索、テキスト選択を処理します。ダイアログ終了時にブロブURLは取り消されます。
Markdown (md、markdown)— Markdig の高度な拡張機能(テーブル、タスクリスト、フェンスコード、オートリンク、脚注)を備えてサーバーサイドでHTMLに変換され、 プレビュー タブに表示されます。2つ目の テキスト タブでは、構文がハイライトされた生のソースが表示されます。ソースの生のHTMLパススルーはレンダリング前に削除されるため、 .md が <script> や <iframe>を密かに持ち込むことはできません。
ソースおよび構造化テキスト (JSON、XML、YAML、YML、HTML、HTM、JS、TS、CS、CSS)—highlight.js 色付け付きで<pre>でレンダリングされます。言語はFileTypeIcons.GetSyntaxLanguageを通じて拡張機能から選ばれ、アセットサイズを小さく保つために宣伝されている言語のみがバンドルされています。ハイライトはJSのインターオペーション上で共置されたFilePreviewDialog.razor.tsモジュールを通過し、インターオペーション呼び出しが失敗するとダイアログは無音で無色テキストに戻ります。
プレーンテキスト (txt、log、csv)— ハイライトなしの <pre> でレンダリングされます。 highlightAuto は意図的に使われていません。なぜなら、短い断片(小さなログや単一のCSV行)を推測すると、色が全くないよりも混乱を招くからです。
zipアーカイブ (zip)— System.IO.Compression.ZipArchive でメモリ上で解析され、分割されたペインとしてレンダリングされます。左側に折りたたみ可能なツリー(フォルダーが先に、アルファベット順、エントリごとのサイズと最終修正がホバー表示)、選択したエントリのプレビューが右側に表示されます。右側のペインは入れ子状の FilePreviewContentなので、内部ファイルは同じレンダラー検索を経て、画像、PDF、ハイライトされたソース、マークダウン、さらにはzip内のzipまでも、すべて単体でプレビューするのと同じ方法で行われます。アーカイブはディスクに解凍されることはありません。
全てダウンロード(zip)
ツールバーの「All ダウンロード」ボタンは、グリッド上で現在レンダリングされているすべてのファイルを、サーバーサイドの内蔵メモリの単一のzipとして ZipArchive 経由でストリーミングし、Blazor回路を経由して送信します。追加のHTTPエンドポイントは不要です。重複するファイル名には (2)、 (3) 接尾辞が付けられます。 AllowDownloadAll="false" でボタンを非表示にし、行ごとのダウンロードアイコンを無効にしないでください。
React
<FileGrid tableName="ppp_file"
fileColumn="ppp_data"
allowDownloadAll={false} />
Blazor
<FileGrid TableName="ppp_file"
FileColumn="ppp_data"
AllowDownloadAll="false" />
作成されたレコードのカスタマイズ
デフォルトでは、アップロードされた各ファイルはファイルの列のみが入力された最小限のレコードを作成します。追加の必要な列があるテーブルや他のデータのシードの場合は、完全に入力されたTableRecordを返すOnUploadRecordAsyncを返します。デリゲートは非同期なので、サービスのコンサルティング、検索の解決、名前の生成ができるので、戻ってきます。
React
<FileGrid tableName="ppp_file"
fileColumn="ppp_data"
onUploadRecordAsync={buildFileRecord} />
async function buildFileRecord(fileName: string, data: Uint8Array): Promise<TableRecord> {
return {
tableName: 'ppp_file',
properties: {
ppp_filename: { $type: 'StringValue', value: fileName },
ppp_data: {
$type: 'FileValue',
fileName,
id: '00000000-0000-0000-0000-000000000000',
value: data,
},
},
} as TableRecord;
}
Blazor
<FileGrid TableName="ppp_file"
FileColumn="ppp_data"
OnUploadRecordAsync="BuildFileRecord" />
@code {
private async Task<TableRecord> BuildFileRecord(string fileName, byte[] data)
{
var record = new TableRecord { TableName = "ppp_file" };
record["ppp_filename"] = new StringValue { Value = fileName };
record["ppp_data"] = new FileValue
{
FileName = fileName,
Id = Guid.Empty,
Value = data,
};
return record;
}
}
MainContext / RecordContext 統合
グリッドが MainContext や RecordContextに入れ子されている場合、アップロードはすぐに作成されるのではなく、グリッドの保留中作成リストに段階的に移行されます。親コンテキストの IsDirty は trueに切り替わり、 SaveAsync 段階化されたレコード( FileValue バイト付き)が ExecuteMultipleAsync にバッチ処理されます。これは各レコードのチャンクファイルアップロードを処理します。これにより、ファイルのアップロードはフォームの他の部分とトランザクション関係で維持されます。
React
<MainContext>
<MenuBar>
<SaveContextButton />
<RefreshContextButton />
</MenuBar>
<FileGrid tableName="ppp_file"
fileColumn="ppp_data" />
</MainContext>
Blazor
<MainContext>
<MenuBar>
<SaveContextButton />
<RefreshContextButton />
</MenuBar>
<FileGrid TableName="ppp_file"
FileColumn="ppp_data" />
</MainContext>
保留中の作成行はグリッドにすぐにファイルタイプアイコンとファイル名が表示されますが、プレビューやダウンロードアイコンは含まれていません(サーバーファイルはまだありません)。コンテキストが保存されると保留中リストから削除されるか、 RefreshContextButton や MainContext.ResetState()でリセットされます。
反応してください
ブレイザー
FileGrid クラス パラメータ
AllowChangingPageSizebool True
AllowDownloadAllbool True
AllowDownloadForFileColumnsbool True
AllowedExtensionsIReadOnlyCollection<string>?
AllowPreviewForFileColumnsbool True
AllowSearchbool True
AutoAddFileColumnIfMissingFromViewbool True
BorderVisiblebool True
ButtonsRenderFragment?
CustomViewDefinitionsList<GridViewDefinition>?
DefaultItemsPerPageint 50
DefaultViewIdGuid?
FileColumn* string
FullSizebool False
HidePagingbool False
IncludeSearchInPersistedStatebool False
MaxFileSizeByteslong 134217728
MaxHeightstring?
MinHeightstring?
OnUploadRecordAsyncFunc<string, byte[], Task<TableRecord>>?
PageSizesIEnumerable<int>
PagingModeGridPagingMode
Paged
PersistedStateQueryParameterstring?
SelectedRecordsIEnumerable<TableRecord>
SelectFromEntireRowbool True
SelectModeDataGridSelectMode
Multiple
TableName* string
Titlestring?
TransformViewAsyncFunc<GridViewDefinition, Task<GridViewDefinition>>?
ViewIdsIEnumerable<Guid>?
ViewSortViewSort
NameAscending
名称:
AllowChangingPageSize
種類:
bool
デフォルト:
True
名称:
AllowDownloadAll
種類:
bool
デフォルト:
True
名称:
AllowDownloadForFileColumns
種類:
bool
デフォルト:
True
名称:
AllowedExtensions
種類:
IReadOnlyCollection<string>?
名称:
AllowPreviewForFileColumns
種類:
bool
デフォルト:
True
名称:
AllowSearch
種類:
bool
デフォルト:
True
名称:
AutoAddFileColumnIfMissingFromView
種類:
bool
デフォルト:
True
名称:
BorderVisible
種類:
bool
デフォルト:
True
名称:
Buttons
種類:
RenderFragment?
名称:
CustomViewDefinitions
種類:
List<GridViewDefinition>?
名称:
DefaultItemsPerPage
種類:
int
デフォルト:
50
名称:
DefaultViewId
種類:
Guid?
名称:
FileColumn*
種類:
string
名称:
FullSize
種類:
bool
デフォルト:
False
名称:
HidePaging
種類:
bool
デフォルト:
False
名称:
IncludeSearchInPersistedState
種類:
bool
デフォルト:
False
名称:
MaxFileSizeBytes
種類:
long
デフォルト:
134217728
名称:
MaxHeight
種類:
string?
名称:
MinHeight
種類:
string?
名称:
OnUploadRecordAsync
種類:
Func<string, byte[], Task<TableRecord>>?
名称:
PageSizes
種類:
IEnumerable<int>
名称:
PagingMode
種類:
GridPagingMode
デフォルト:
Paged
名称:
PersistedStateQueryParameter
種類:
string?
名称:
SelectedRecords
種類:
IEnumerable<TableRecord>
名称:
SelectFromEntireRow
種類:
bool
デフォルト:
True
名称:
SelectMode
種類:
DataGridSelectMode
デフォルト:
Multiple
名称:
TableName*
種類:
string
名称:
TransformViewAsync
種類:
Func<GridViewDefinition, Task<GridViewDefinition>>?
名称:
ViewIds
種類:
IEnumerable<Guid>?
名称:
ViewSort
種類:
ViewSort
デフォルト:
NameAscending
イベント
SelectedRecordsChangedEventCallback<IEnumerable<TableRecord>>
名称:
SelectedRecordsChanged
種類:
EventCallback<IEnumerable<TableRecord>>