2

I am implementing custom xDB facets in Sitecore 8.1-3. I have a facet called "Marketing Data". Most of the elements of "Marketing Data" are simple strings. I also have an element called "Shipping Addresses" that is a list of "Address" elements. It is unclear to me how to add a new element to the list. I see that the IElementCollection class has a Create method, but no Add method.

My Marketing Data facet interface looks like this

public interface IMarketingData : IFacet
{
    string Organization { get; set; }
    string Industries { get; set; }
    string ProductTypes { get; set; }
    IElementCollection<IAddress> ShippingAddresses { get; }
}

The implementation of Marketing Data looks like this

[Serializable]
public class MarketingData : Facet, IMarketingData
{
    private const string ORGANIZATION = "Organization";
    private const string INDUSTRIES = "Industries";
    private const string SHIPPINGADDRESSES = "ShippingAddresses";
    private const string PRODUCTTYPES = "ProductTypes";

    public string Organization
    {
        get { return GetAttribute<string>(ORGANIZATION); }
        set { SetAttribute(ORGANIZATION, value); }
    }

    public string Industries
    {
        get { return GetAttribute<string>(INDUSTRIES); }
        set { SetAttribute(INDUSTRIES, value); }
    }

    public IElementCollection<IAddress> ShippingAddresses
    {
        get { return GetCollection<IAddress>(SHIPPINGADDRESSES); }
    }

    public string ProductTypes
    {
        get { return GetAttribute<string>(PRODUCTTYPES); }
        set { SetAttribute(PRODUCTTYPES, value); }
    }

    public MarketingData()
    {
        EnsureAttribute<string>(ORGANIZATION);
        EnsureAttribute<string>(INDUSTRIES);
        EnsureCollection<IAddress>(SHIPPINGADDRESSES);
        EnsureAttribute<string>(PRODUCTTYPES);
    }
}

The interface for my address facet looks like this

public interface IAddress : IElement
{
    Guid Id { get; set; }
    string Company { get; set; }
    string Address1 { get; set; }
    string Address2 { get; set; }
    string City { get; set; }
    string Country { get; set; }
    string State { get; set; }
    string PostalCode { get; set; }
}

Then I have code where I want to add a new address to an existing contact. It looks like this

...code to get a contact from xDB and put it in lockedContact variable...

var marketingInfo = lockedContact.GetFacet<IMarketingData>("Marketing Data");

marketingInfo.Organization = txtOrganization.Text;
marketingInfo.Industries = txtIndustries.Text;
marketingInfo.ProductTypes = txtProductTypes.Text;

var newAddress = marketingInfo.ShippingAddresses.Create(); //Fails here
newAddress.Address1 = txtAddress1.Text;
newAddress.Address2 = txtAddress2.Text;
newAddress.City = txtCity.Text;
newAddress.State = txtState.Text;
newAddress.Country = txtCountry.Text;
newAddress.PostalCode = txtPostalCode.Text;
newAddress.Company = txtCompany.Text;

Am I using the Create method correctly? It doesn't seem like there is any way to pass an object in to the Create method so I am unsure how I would set the different address properties.

  • You are using the Create method correctly. When you say "Fails here", what do you mean exactly? If there's an exception thrown, please attach the full error with stack trace. – Dmytro Shevchenko Dec 10 '16 at 16:26
  • Also, did you register Address as your IAddress implementation in Sitecore configuration? You can do it under <sitecore> - <model> - <elements> — see examples in Sitecore.Analytics.Model.config. – Dmytro Shevchenko Dec 10 '16 at 16:30
  • Can you show us your config files for the <entities> section? – Chris Auer Dec 12 '16 at 2:29
  • That was it! I was missing the registration of IAddress in my config file. Thanks so much to @DmytroShevchenko! – Corey Burnett Dec 12 '16 at 15:29
4

You need to register Address as your IAddress implementation in Sitecore configuration. You can see how it is done in Sitecore.Analytics.Model.config.

Basically, you'd have a patch file along the lines of:

<?xml version="1.0" encoding="utf-8"?>
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore>
    <model>
      <elements>
        <element
          interface="SomeNamespace.IAddress, SomeAssembly"
          implementation="SomeNamespace.Address, SomeAssembly" />
      </elements>
    </model>
  </sitecore>
</configuration>
  • Thanks so much. I didn't realize that I needed to register all elements, even those that are sub-elements of a different element. – Corey Burnett Dec 12 '16 at 15:33
  • @CoreyBurnett You are welcome. Even though you can register your collection successfully like tihs: EnsureCollection<IAddress>(...), when you call Create() on that collection, Sitecore will need to know what implementation of IAddress it should use. Otherwise, it won't be able to create a new element and hence your code will fail with an error. – Dmytro Shevchenko Dec 12 '16 at 15:35

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.