public class ContactDataModel : Sitecore.ListManagement.Services.Model.ContactDataModel2. Data is mapped by the Sitecore.ListManagement.Services.Repositories.ListSubscriptionsStore class (retrieve the code using IL Spy, .NET Reflector, or any other reverse engineering tool). Create your own class that has a GetSubscribers method returning IEnumerable of your custom model as follows:
{
public string FavouriteBrand { get; set; }
}
public IEnumerable<CustomNamespace.ContactDataModel> GetSubscribers(Guid listId, string searchFilter, int pageIndex, int pageSize)Note: The data is retrieved from _contactProvider and converted to the specified model using the MapEntity method.
{
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;
}
CustomNamespace.ContactDataModel model1 = new CustomNamespace.ContactDataModel();The _contactProvider.GetFilteredContacts method returns only three facets (ListSubscriptions, Personal, Emails). So, add the custom ones to the list:
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;
IContactSource contactSource = this._contactSourceFactory.GetSource(contactList);3. The default ListSubscriptionsStore is used by the Sitecore.ListManagement.Services.Controllers.ContactsController controller. Create your custom controller, which performs the same actions and changes the GetEntries method to use the custom ListSubscriptionsStore.
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));
public class CustomContactsController : ServicesApiController4. Change the RoutePrefix attribute value of the controller to sitecore/api/customlists/{listId}/contacts.
{
// Add a parametreless constructor to your controller
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); // create your custom store
}
..........
[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); // your custom store must be used here
}
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>();
}
}
}
public class RegisterHttpRoutes6. Build the assembly and put it in the bin folder of your site.
{
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", // Name of the action in ActionName attribute
});
}
}
After performing all these steps, you can upload a CSV list containing custom facets.
Note: The given algorithm is intended as an example and can be extended and changed according to your requirements.