3

I want to add custom fields to my import wizard and import a list with values for those new fields. Looking at the examples online this appears to be straight forward. But I am getting an error in the facet mapper when I execute the import.

This is the error thrown in the Sitecore Service. How do I get past this exception? 9608 14:44:31 ERROR [Sitecore Services]: HTTP POST URL http://{site_removed}/sitecore/api/ssc/ListManagement/Import/{Guid_ID_Removed}/ImportContactsFromMediaLibraryAndCreateList Exception System.Collections.Generic.KeyNotFoundException: The given key was not present in the dictionary. at System.Collections.Generic.Dictionary`2.get_Item(TKey key) at Sitecore.ListManagement.Import.FacetedMapper.Map(MappingInfo mappingInfo, Object destination, MappingContext context)

The error message fits many scenarios but we know that there is a dictionary somewhere that’s using a key value and the code can't find the key.

There is a considerable amount of code and configuration that goes into this.

I've created the field content items in the Content manger on the CORE database and updated the tree at the List manager node from the Developer's tab in CORE and MASTER. My fields show up in the wizard as expected.

Code:

Interface

public interface IABCCompanyContactDetailFacet : IFacet
{
    string AbcName { get; set; }
    string AbcNumber { get; set; }
}

Class (uses the serializable attribute)

 public class ABCCompanyContactDetailFacet : Facet, IABCCompanyContactDetailFacet
{
    private const string ABCNAME = "ABCName";
    private const string ABCNUMBER = "ABCNumber";

    public ABCCompanyContactDetailFacet()
    {
        this.EnsureAttribute<string>(ABCNAME);
        this.EnsureAttribute<string>(ABCNUMBER );
    }

    public string AbcName
    {
        get { return this.GetAttribute<string>(ABCNAME ); }

        set { this.SetAttribute<string>(ABCNAME , value); }
    }

    public string AbcNumber
    {
        get { return this.GetAttribute<string>(ABCNUMBER ); }

        set { this.SetAttribute<string>(ABCNUMBER , value); }
    }

}

Sitecore.Analytics.Model.config

 <elements>
     <element interface="ABCCompany.Analytics.CustomFacets.IABCContactDetailFacet, ABCCompany.Analytics" implementation="ABCCompany.Analytics.CustomFacets.ABCContactDetailFacet, ABCCompany.Analytics"/>
  </elements>

 <facets>
    <facet name="ABCContactDetail" contract="ABCCompany.Analytics.CustomFacets.IABCContactDetailFacet, ABCCompany.Analytics" />
 </facets>

Sitecore.Analytics.config

      <updateFields>
        <processor type="Sitecore.ListManagement.Analytics.Data.Bulk.Contact.Pipelines.UpdateFields.DeepCopyFacet`1[[ABCCompany.Analytics.CustomFacets.IABCContactDetailFacet, ABCCompany.Analytics]], Sitecore.ListManagement.Analytics">
            <param desc="facetName">ABCContactDetail</param>
        </processor>
      </updateFields>

Content Manager (Core) (Data field example. This is similar to what I used.)

 Item path: /sitecore/client/Applications/List Manager/Dialogs/ImportWizardDialog/PageSettings/TabControl Parameters/Map/ImportModel/ABC Name

 Item path: /sitecore/client/Applications/List Manager/Dialogs/ImportWizardDialog/PageSettings/TabControl Parameters/Map/ImportModel/ABC Number

Field Name similar to: (Code Property Names are the same as Field Name)

AbcName

AbcNumber

Data Value fields similar to:

{facet:"ABCContactDetail", property:"AbcName"}

{facet:"ABCContactDetail", property:"AbcNumber"}

After the set up above the new fields are available. I attempt to import the file and I get a red message saying that "The contacts have not been imported."

I only have one record in the test csv file.

The csv text is below (header and one row of data). (ID: I tried with INT , GUID, and no Identifier ID with same results)

Email,First_Name,Last_Name,ABCNumber,ABCName,ID customer1@gmail.com,CustomerFirst,CustomerLast,ABC Number Value,ABC Name Value,{8e558fdc-67b8-4bc5-8e18-92c78ad33cb0}

1

The issue that you are seeing is that the Facet Mapper dictionary is case sensitive.

In your example above, the String constant that you are setting in your concrete class is private const string ABCNAME = "ABCName". Note that the "ABC" is Capitalized.

However, in your ImportModel field definition, you have {facet:"ABCContactDetail", property:"AbcName"} where there property is listed as "AbcName". Notice that the ABC is not capitalized like it is in your Facet concrete class.

Change your ImportModel field to uppercase ABC, and this should work.

Nice work by the way. Looks like you hit all of the main points.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.