1

I have a model which has two nested classes within. I am unable to find any resources how to map this correctly.

In Sitecore the Address.cs corresponds to the template Address which has a droplink to a Market. The market contains several fields which should me mapped to Market.cs as well as a single-text field which should be mapped to Text.cs.

public class Address{

    [SitecoreField(FieldName = Templates.AddressItem.Fields.Market_FieldName)]
    public virtual Market Market {get; set;}
    .... other properties
}

With the Market.cs model:

public class Market{
    [SitecoreField(FieldName = Templates.MarketItem.Fields.MarketName_FieldName)]
    public virtual Text Name {get; set}
    ... other properties
}

And Text.cs

public class Text{
    public virtual string Text {get; set;}
    public virtual bool IsStandardValue {get; set;}
    ... other properties
}

Obviously, directly mapping it using [SitecoreField(FieldName = Templates.AddressItem.Fields.Market_FieldName)] does not work.

How would I map the Market object, and the Text object properly as well as the IsStandardValue? (Can be gotten from Item.Field.ContainsStandardValue.)

  • What is the name, in Sitecore, of the fields "Market" and "Name"? – Emanuele Ciriachi May 9 '19 at 11:20
  • "Market" and "MarketName" – Jerry Hu May 9 '19 at 11:22
  • Did you try [SitecoreField("Market")] and [SitecoreField("MarketName")] and using virtual for both? In the first case you don't even need SitecoreField - I only use it if the name of the field differs from that of the Sitecore one (or if the Sitecore one has spaces in it). – Emanuele Ciriachi May 9 '19 at 11:24
  • 1
    Sorry it should already have been virtual. The Templates.MarketItem.Fields.MarketItem_FieldName cotains the strings you mentoined. But this throws a GlassMapper.Mapper.MapperException since it does not know how to map a droplink field into a Market object, which propagates to it not knowing how to map a text field to a Text object. – Jerry Hu May 9 '19 at 12:12
1

You can use the attribute [SitecoreSelf] to continue mapping the current item on a nested object:

public class Market
{
    [SitecoreSelf]
    public virtual Text Name { get; set }
}

Then on the Text class you add the [SitecoreField] attribute to get the text field mapped.

public class Text
{
    [SitecoreField(FieldName = Templates.MarketItem.Fields.MarketName_FieldName)]
    public virtual string Text {get; set;}

    // Use custom mapper
    [DataMapper(typeof(ContainsStandardValueMapper))]
    [SitecoreField(FieldName = Templates.MarketItem.Fields.MarketName_FieldName)]
    public virtual bool IsStandardValue {get; set;}
}

For for the IsStandardValue property you need to create a custom mapper.

public class ContainsStandardValueMapper : AbstractDataMapper
{
    public override void MapToCms(AbstractDataMappingContext mappingContext)
    {
        throw new NotImplementedException();
    }

    public override object MapToProperty(AbstractDataMappingContext mappingContext)
    {
        var scConfig = Configuration as SitecoreFieldConfiguration;
        var scContext = mappingContext as SitecoreDataMappingContext;

        var field = Glass.Mapper.Sc.Utilities.GetField(scContext.Item, scConfig.FieldId, scConfig.FieldName);

        if (field == null)
            return false;

        return field.ContainsStandardValue;
    }

    public override bool CanHandle(AbstractPropertyConfiguration configuration, Context context)
    {
        throw new NotImplementedException();
    }
}

If you often use the Text class pattern then maybe it would make sense to create a custom mapper for that type instead.

| improve this answer | |
  • Hi Soren, it partially solved my problem so I accepted it. However, my Configuration is null so I can't get the field. Any idea why? – Jerry Hu Jul 4 '19 at 14:24
0

Make sure all of your models have the [SitecoreType] attribute on them, too:

[SitecoreType(TemplateId = "{ADDRESS-TEMPLATE-ID}")]
public class Address {
    [SitecoreField(FieldName = Templates.AddressItem.Fields.Market_FieldName)]
    public virtual Market Market {get; set;}
    .... other properties
}

[SitecoreType(TemplateId = "{MARKET-TEMPLATE-ID}")]
public class Market {
    [SitecoreField(FieldName = Templates.MarketItem.Fields.MarketName_FieldName)]
    public virtual string Name {get; set}
    ... other properties
}
| improve this answer | |
  • Hi, the Text object is not a Sitecore item but a single-line text field, so that field needs to be mapped to the Text object, how would I do that? – Jerry Hu May 10 '19 at 11:42
  • In that case, you can just use string for the type for that field. I'm not sure how to populate a property like IsStandardValue, but that's probably a separate question, so I would recommend asking a new one with that specific question. – Dan Sinclair May 10 '19 at 11:45

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.