2

I have the following code to reference a custom facet.

var contact = Tracker.Current.Session.Contact;
IHistoryFacet history = contact.GetFacet<IHistoryFacet>("History");
IHistoryLocationElement historyLocation = history.Locations.Create();

It appears to fail on the last line with an error of:

System.Collections.Generic.KeyNotFoundException: The given key was not present in the dictionary.

I do not understand why.

This is my HistoryFacet.cs file:

using Sitecore.Analytics.Model.Framework;
using System;

namespace MySite.Models.Facets
{
    [Serializable]
    public class HistoryFacet : Facet, IHistoryFacet
    {
        private const string FACET_NAME = "History";
        private const string COLLECTION_CHANGE = "Changes";
        private const string COLLECTION_LOCATION = "Locations";

        public HistoryFacet()
        {
            EnsureCollection<IHistoryChangeElement>(COLLECTION_CHANGE);
            EnsureCollection<IHistoryLocationElement>(COLLECTION_LOCATION);
        }

        public IElementCollection<IHistoryChangeElement> Changes
        {
            get
            {
                return GetCollection<IHistoryChangeElement>(FACET_NAME);
            }
        }

        public IElementCollection<IHistoryLocationElement> Locations
        {
            get
            {
                return GetCollection<IHistoryLocationElement>(FACET_NAME);
            }
        }
    }
}

Here is my HistoryLocationElement.cs file:

using Sitecore.Analytics.Model.Framework;
using System;
using System.Net;

namespace MySite.Models.Facets
{
    [Serializable]
    public class HistoryLocationElement : Element, IHistoryLocationElement
    {
        private const string FIELD_DATE = "Date";
        private const string FIELD_IP_ADDRESS = "IP Address";
        private const string FIELD_STREET_ADDRESS_LINE_01 = "Street Address Line 1";
        private const string FIELD_STREET_ADDRESS_LINE_02 = "Street Address Line 2";
        private const string FIELD_STREET_ADDRESS_LINE_03 = "Street Address Line 3";
        private const string FIELD_STREET_ADDRESS_LINE_04 = "Street Address Line 4";
        private const string FIELD_CITY = "City";
        private const string FIELD_METRO_CODE = "Metro Code";
        private const string FIELD_REGION = "Region";
        private const string FIELD_REGION_CODE = "Region Code";
        private const string FIELD_POSTAL_CODE = "Postal Code";
        private const string FIELD_COUNTRY = "Country";
        private const string FIELD_COUNTRY_CODE = "Country Code";
        private const string FIELD_LONGITUDE = "Longitude";
        private const string FIELD_LATITUDE = "Latitude";
        private const string FIELD_ZENITH = "Zenith";
        private const string FIELD_TIMEZONE = "Timezone";

        public HistoryLocationElement()
        {
            EnsureAttribute<DateTime>(FIELD_DATE);
            EnsureAttribute<IPAddress>(FIELD_IP_ADDRESS);
            EnsureAttribute<string>(FIELD_STREET_ADDRESS_LINE_01);
            EnsureAttribute<string>(FIELD_STREET_ADDRESS_LINE_02);
            EnsureAttribute<string>(FIELD_STREET_ADDRESS_LINE_03);
            EnsureAttribute<string>(FIELD_STREET_ADDRESS_LINE_04);
            EnsureAttribute<string>(FIELD_CITY);
            EnsureAttribute<int>(FIELD_METRO_CODE);
            EnsureAttribute<string>(FIELD_REGION);
            EnsureAttribute<string>(FIELD_REGION_CODE);
            EnsureAttribute<string>(FIELD_POSTAL_CODE);
            EnsureAttribute<string>(FIELD_COUNTRY);
            EnsureAttribute<string>(FIELD_COUNTRY_CODE);
            EnsureAttribute<double>(FIELD_LONGITUDE);
            EnsureAttribute<double>(FIELD_LATITUDE);
            EnsureAttribute<double>(FIELD_ZENITH);
            EnsureAttribute<string>(FIELD_TIMEZONE);
        }

        public DateTime Date
        {
            get { return GetAttribute<DateTime>(FIELD_DATE); }
            set { SetAttribute(FIELD_DATE, value); }
        }
        public IPAddress IPAddress
        {
            get { return GetAttribute<IPAddress>(FIELD_IP_ADDRESS); }
            set { SetAttribute(FIELD_IP_ADDRESS, value); }
        }
        public string StreetAddressLine01
        {
            get { return GetAttribute<string>(FIELD_STREET_ADDRESS_LINE_01); }
            set { SetAttribute(FIELD_STREET_ADDRESS_LINE_01, value); }
        }
        public string StreetAddressLine02
        {
            get { return GetAttribute<string>(FIELD_STREET_ADDRESS_LINE_02); }
            set { SetAttribute(FIELD_STREET_ADDRESS_LINE_02, value); }
        }
        public string StreetAddressLine03
        {
            get { return GetAttribute<string>(FIELD_STREET_ADDRESS_LINE_03); }
            set { SetAttribute(FIELD_STREET_ADDRESS_LINE_03, value); }
        }
        public string StreetAddressLine04
        {
            get { return GetAttribute<string>(FIELD_STREET_ADDRESS_LINE_04); }
            set { SetAttribute(FIELD_STREET_ADDRESS_LINE_04, value); }
        }
        public string City
        {
            get { return GetAttribute<string>(FIELD_CITY); }
            set { SetAttribute(FIELD_CITY, value); }
        }
        public int MetroCode
        {
            get { return GetAttribute<int>(FIELD_METRO_CODE); }
            set { SetAttribute(FIELD_METRO_CODE, value); }
        }
        public string Region
        {
            get { return GetAttribute<string>(FIELD_REGION); }
            set { SetAttribute(FIELD_REGION, value); }
        }
        public string RegionCode
        {
            get { return GetAttribute<string>(FIELD_REGION_CODE); }
            set { SetAttribute(FIELD_REGION_CODE, value); }
        }
        public string PostalCode
        {
            get { return GetAttribute<string>(FIELD_POSTAL_CODE); }
            set { SetAttribute(FIELD_POSTAL_CODE, value); }
        }
        public string Country
        {
            get { return GetAttribute<string>(FIELD_COUNTRY); }
            set { SetAttribute(FIELD_COUNTRY, value); }
        }
        public string CountryCode
        {
            get { return GetAttribute<string>(FIELD_COUNTRY_CODE); }
            set { SetAttribute(FIELD_COUNTRY_CODE, value); }
        }
        public double Longitude
        {
            get { return GetAttribute<double>(FIELD_LONGITUDE); }
            set { SetAttribute(FIELD_LONGITUDE, value); }
        }
        public double Latitude
        {
            get { return GetAttribute<double>(FIELD_LATITUDE); }
            set { SetAttribute(FIELD_LATITUDE, value); }
        }
        public double Zenith
        {
            get { return GetAttribute<double>(FIELD_ZENITH); }
            set { SetAttribute(FIELD_ZENITH, value); }
        }
        public string Timezone
        {
            get { return GetAttribute<string>(FIELD_TIMEZONE); }
            set { SetAttribute(FIELD_TIMEZONE, value); }
        }
    }
}

Here is my IHistoryFacet.cs file:

using Sitecore.Analytics.Model.Framework;

namespace MySite.Models.Facets
{
    public interface IHistoryFacet : IFacet
    {
        IElementCollection<IHistoryChangeElement> Changes { get; }
        IElementCollection<IHistoryLocationElement> Locations { get; }
    }
}

Here is my IHistoryLocationElement.cs file:

using Sitecore.Analytics.Model.Framework;
using System;
using System.Net;

namespace MySite.Models.Facets
{
    public interface IHistoryLocationElement : IElement
    {
        DateTime Date { get; set; }
        IPAddress IPAddress { get; set; }
        string StreetAddressLine01 { get; set; }
        string StreetAddressLine02 { get; set; }
        string StreetAddressLine03 { get; set; }
        string StreetAddressLine04 { get; set; }
        string City { get; set; }
        int MetroCode { get; set; }
        string Region { get; set; }
        string RegionCode { get; set; }
        string PostalCode { get; set; }
        string Country { get; set; }
        string CountryCode { get; set; }
        double Longitude { get; set; }
        double Latitude { get; set; }
        double Zenith { get; set; }
        string Timezone { get; set; }
    }
}

I am not sure what key it is referring to.

4

Your collection getters need to access the actual collections by using proper keys:

public IElementCollection<IHistoryChangeElement> Changes
{
    get
    {
        return GetCollection<IHistoryChangeElement>(COLLECTION_CHANGE);
    }
}

public IElementCollection<IHistoryLocationElement> Locations
{
    get
    {
        return GetCollection<IHistoryLocationElement>(COLLECTION_LOCATION);
    }
}

Note that I used COLLECTION_CHANGE and COLLECTION_LOCATION instead of FACET_NAME.

Those are the keys you used when you ensured these collections in the constructor:

EnsureCollection<IHistoryChangeElement>(COLLECTION_CHANGE);
EnsureCollection<IHistoryLocationElement>(COLLECTION_LOCATION);

So now you should use the same keys to access them.

The KeyNotFoundException is thrown because there are no collections registered in the facet with the key FACET_NAME.

| improve this answer | |
  • Wow, it is so Monday. I missed that mismatch. – eat-sleep-code Oct 24 '16 at 19:51

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.