WebClient SDK を使用してプログラムからアセットファイルをアップロードする方法

samatsu 2/7/2023 190 N/A Sitecore Content Hub

Sitecore Content Hub が提供する WebClient SDK を使用してアセットエンティティをアップロードして作成したり更新するためのヒントとなるページのリンクをまとめておきます。

NuGetとVSの基本設定

VSのセットアップの基本設定は次のページから確認できます。

https://doc.sitecore.com/ch/en/developers/42/cloud-dev/web-sdk--get-started.html

認証の設定は、次のURLのページを参照

https://doc.sitecore.com/ch/en/developers/42/cloud-dev/web-sdk--authentication.html

ファイルのアップロード

ローカルファイルやHTTPでアクセス可能なリモートノードのファイルをアップロードできる。

https://doc.sitecore.com/ch/en/developers/42/cloud-dev/sdk-common-documentation--upload-client.html

上記ページのAssetUploadConfigurationやNewAssetの意味については下記URLを参照

https://doc.sitecore.com/ch/en/developers/42/cloud-dev/rest-api--upload-api-v2.html

拡張子の許可

アップロードを許可したい拡張子のコントロールは

Entitiesマネージャ画面からM.UploadConfiguration エンティティ定義のAssetUploadConfigurationエンティティにアクセスして、allowed_extensions に拡張子を追加。

トラブルシューティング

診断ログの有効化

https://doc.sitecore.com/ch/en/developers/42/cloud-dev/web-sdk--diagnostics.html

ログの出力

https://doc.sitecore.com/ch/en/developers/42/cloud-dev/sdk-common-documentation--logging.html

コンソールのログを出力する場合は、ConsoleLoggerを使用できる。

_client.Value.Logger = new ConsoleLogger();

また、現時点のWebClientSDKのバージョン4.2.4の実装だと、"なぜか"、HttpUploadSource を使用した場合、リモートソース(例えばAzure Blob)からファイルをアップロードしようとすると、Content HubにアクセスするためのBearerトークンを画像を公開しているリモートのサーバーに送信してくれます。Azure Blobの場合AuthorizationヘッダーにBearerトークンがあると403コードを返すのでアップロードに失敗します。これはどういうことなのかというと実は、Azure Blobなどリモートをソースと指定しても実際にはローカルにダウンロードするという処理を行ってくれているみたいです。なので、初めからLocalUploadSourceを使用したほうが簡単説があります。

いずれにしよ画像がアップロードされているURLに画像データを取得する際、Content HubのAPIアクセス用のBearerトークンを付けてくれるので、これを回避するために 下記のような簡易的なIUploadSourceを実装しました。

   public class AzureBlobUploadSource : IUploadSource
    {
        private readonly Uri _uri;
        public string Name { get; private set; }
        public AzureBlobUploadSource(Uri uri, string name = "")
        {
            this._uri = uri;
            if (string.IsNullOrEmpty(name))
            {
                this.Name = Path.GetFileName(uri.LocalPath);
            }
            else
            {
                this.Name = name;
            }
        }

        public async Task<Stream> GetStreamAsync()
        {
            var httpClient = new HttpClient();
            var message = await httpClient.GetAsync(this._uri);
            return message.Content.ReadAsStream();
        }
    }

以上となります。実は最後の部分が一番はまりました。