連絡先のリストのビューを拡張してデフォルトのファセットの代わりに追加のファセットを表示させる方法


説明

ユーザー様が連絡先のファセットを追加で表示させるようList Managerを拡張する際に、困難に直面する場合があります。
本記事では、Contactsテーブルにカラムを追加するためのアルゴリズムについて説明します。

解決策

重要:変更を適用する前に、ソリューションのバックアップを実施してください。

  1. 以下の記事に従って、カスタムのファセットをラップしたカスタム モデルを作成し、デプロイします。
    カスタム モデルの作成
    カスタム モデルのデプロイ
  2. Contactsテーブルにカスタムのファセット用のカラムを追加します:
    1. Coreデータベースに切り替えます。
    2. /sitecore/client/Applications/List Manager/Lists/Contactリスト アイテムに新しいColumnFieldアイテムを追加します。
    3. 新しく作成されたアイテムで、次のフィールドを記入します:
    • EmptyText(セルにデータが含まれていない場合では、デフォルトのテキストを指定します)
    • HeaderText(カラム名)
    • DataField(データ ソースを使用したカスタム ファセット名)
    4. 変更を保存します。その後、新しいカラムはList Managerアプリケーションに表示されます。
  3. 以下の記事の説明に従って、カスタム連絡先ファセットを含めるよう、連絡先のインポート ウィザード ダイアログを設定します。
    カスタム コンタクト ファセットを含めるように [コンタクトをインポートする] ウィザードを設定する
  4. カスタムの連絡先コントローラを作成します。
    1. 必要なファセットを含むカスタムのContactDataModelを作成します。例えば:
    public class ContactDataModel : Sitecore.ListManagement.Services.Model.ContactDataModel
    {
    public string FavouriteBrand { get; set; }
    }
    2. データは、Sitecore.ListManagement.Services.Repositories.ListSubscriptionsStoreクラスでマップされます(IL Spy、.NET Reflectorまたは他のリバース エンジニアリング ツールでコードを取得します)。次のように、カスタム モデルのIEnumberableを返すGetSubscribersメソッドを持つ独自のクラスを作成します。
    public IEnumerable<CustomNamespace.ContactDataModel> GetSubscribers(Guid listId, string searchFilter, int pageIndex, int pageSize)
    {
    ContactList contactList = this.EnsureList(listId, null);
    ContactSearchResult result = this._contactProvider.GetFilteredContacts(contactList, searchFilter, pageIndex, pageSize);
    List<CustomNamespace.ContactDataModel> source = result.Contacts.Select<Contact, CustomNamespace.ContactDataModel>(new Func<Contact, CustomNamespace.ContactDataModel>  (this.MapEntity)).ToList<CustomNamespace.ContactDataModel>();
    if (source.Any<ContactDataModel>())
    {
      source[0].Count = result.Count;
    }
    return source;
    }
    備考:データは_contactProviderから取得し、MapEntityメソッドで特定のモデルに変換します。
    MapEntityメソッドにカスタムのマッピング ロジックを挿入します。
    CustomNamespace.ContactDataModel model1 = new CustomNamespace.ContactDataModel();
    Guid? id = entity.Id;
    model1.Id = (id.HasValue ? id.GetValueOrDefault() : Guid.Empty).ToString();
    model1.Email = (entity.Emails()?.PreferredEmail == null) ? null : ((entity.Emails() == null) ? null : (entity.Emails().PreferredEmail)).SmtpAddress;
    model1.FirstName = entity.Personal()?.FirstName;
    model1.LastName = entity.Personal()?.LastName;
    model1.FavouriteBrand = entity.GetFacet<MarketingDataFacet>().FavouriteBrand;
    ContactIdentifier identifier = entity.Identifiers.FirstOrDefault<ContactIdentifier>(x => (x.Source == "ListManager")) ?? entity.Identifiers.FirstOrDefault<ContactIdentifier>();
    model1.Identifier = identifier?.Identifier;
    model1.IdentifierSource = identifier?.Source;
    return model1;
     _contactProvider.GetFilteredContactsメソッドは、3つファセット(ListSubscriptions, Personal, Emails)のみを返します。従って、カスタムのものをリストに追加します:
    IContactSource contactSource = this._contactSourceFactory.GetSource(contactList);
    FilteringSource source2 = new FilteringSource(contactSource, searchFilter);
    string[] facets = new string[] { "ListSubscriptions", "Personal", "Emails", "MarketingDataFacet" };
    return new ContactSearchResult(this._segmentationService.GetContacts(source2, pageSize * pageIndex, pageSize, facets), (int)this._segmentationService.GetCount(contactSource));
    3. Sitecore.ListManagement.Services.Controllers.ContactsControllerコントローラは、デフォルトのListSubscriptionsStoreを使用します。同じアクションを実行するカスタム コントローラを作成し、カスタムのListSubscriptionsStoreを使用するようGetEntriesメソッドを変更します。
     public class CustomContactsController : ServicesApiController
    {
    //  コントローラにパラメーターなしのコンストラクタを追加します。
    public CustomContactsController()
    {
      var clp = Sitecore.DependencyInjection.ServiceLocator.ServiceProvider.GetService<IContactListProvider>();
      var sp = Sitecore.DependencyInjection.ServiceLocator.ServiceProvider.GetService<ISubscriptionService>();
      var csf = Sitecore.DependencyInjection.ServiceLocator.ServiceProvider.GetService<IContactSourceFactory>();
      var sss = Sitecore.DependencyInjection.ServiceLocator.ServiceProvider.GetService<ISegmentationService>();
      var cp = new Sitecore.Support.ListManagement.XConnect.ContactProvider(sss, csf); // create an object of the custom ContactProvider class
      var or = Sitecore.DependencyInjection.ServiceLocator.ServiceProvider.GetService<IListOperationRepository>();
      var lss = Sitecore.DependencyInjection.ServiceLocator.ServiceProvider.GetService<IListSubscriptionsStore<ContactDataModel>>();
      int batchSize = Sitecore.Configuration.Settings.GetIntSetting("ListManagement.BatchSize", 250);
      this._listSubscriptionsStore = new CustomListSubscriptionsStore(clp, sp, cp, or, batchSize); // カスタム ストアを作成します。
    }
    ..........
            
    [Route]
    [HttpGet]
    [ActionName("MyDefaultAction")]
     public virtual IEnumerable<CustomNamespace.ContactDataModel> GetEntities(Guid listId, string filter = "", int pageIndex = 0, int pageSize = 20)
    {
      try
      {
        return this._listSubscriptionsStore.GetSubscribers(listId, filter, pageIndex, pageSize); // カスタム ストアはここで使用します。
      }
      catch (Exception exception) when (!(exception is ContactListNotFoundException))
      {
        this._log.Error(string.Format(CultureInfo.InvariantCulture, "[ListManagement]: Failed to get count of contacts for {0} contact list. The error has been occurred: {1}", listId, exception.Message), exception, this);
        return Enumerable.Empty<ListManagmentViewFacets.ContactDataModel>();
      }
    }
    }        
    4. コントローラのRoutePrefix属性値をsitecore/api/customlists/{listId}/contactsに変更します。
    5. コントローラを登録するプロセッサを作成します。
    public class RegisterHttpRoutes
    {
      public void Process(PipelineArgs args)
      {
        GlobalConfiguration.Configure(Configure);
      }

    protected void Configure(HttpConfiguration configuration)
      {
      var routes = configuration.Routes;
       routes.MapHttpRoute("CustomContacts", "sitecore/api/customlists/{listId}/contacts", new
        {
            controller = "CustomContacts",
            action = "MyDefaultAction", // ActionName属性でのアクションの名称
       });
     }
    }
    6. アセンブリを構築し、サイトのbinフォルダに配置します。
    7. 「<processor type="Sitecore.Mvc.Pipelines.Loader.InitializeRoutes, Sitecore.Mvc" /> 」(<initialize>のパイプライン)の直後に「RegisterHttpRoutes」プロセッサを修正します。
    8. コンテンツ エディタにてCoreデータベースにアクセスし、/sitecore/client/Applications/List Manager/Global Settings/ListTaskPageSettings/ContactsDataSourceパラメーターのアイテムに移動します。URLフィールドを「/sitecore/api/customlists」に変更します。

上記の手順を実施した後、カスタム ファセットを含むCSVリストのアップロードが可能になります。

備考:このアルゴリズムは一例としてご紹介しているものです。貴社のご要件に応じて、拡張・変更することが可能です。