1

I have a Droplink type field called Formatter on a Table Column item. I would like GlassMapper to automatically map the selected value in the DropLink to the concrete class. Is this possible?

using System;
using System.Reflection;
using Glass.Mapper.Sc.Configuration.Attributes;
using TI.Models.Base;
using TI.Web.Utilities.ExceptionLogger;

namespace TI.Web.Models.Generics
{
    [SitecoreType(false, "{ADBE3C0C-E00B-4559-8082-97C2E5FFD592}")]
    public class TableColumn : BaseItem
    {
        private const BindingFlags Inherited = BindingFlags.FlattenHierarchy | BindingFlags.Instance | BindingFlags.Public;

        [SitecoreField]
        public virtual string Header { get; set; }

        [SitecoreField]
        public virtual string Property { get; set; }

        [SitecoreField]
        public virtual string Formatting { get; set; }

        [SitecoreField]
        public virtual ITableColumnFormatter Formatter { get; set; }

        public string GetValue(object row, string type)
        {
            var collectionType = Type.GetType(type);

            try
            {
                Type fieldOrPropertyType;
                if (!Property.Contains("."))
                {
                    return Format(GetFieldOrProperty(row, Property, collectionType, out fieldOrPropertyType));
                }

                var current = row;
                var currentType = collectionType;

                foreach (var step in Property.Split('.'))
                {
                    var fieldOrProperty = GetFieldOrProperty(current, step, currentType, out fieldOrPropertyType);
                    current = fieldOrProperty;
                    currentType = fieldOrPropertyType;
                }

                return Format(current);
            }
            catch
            {
                LogManager.Error($"Unable to get field/property {Property} from TableColumn item {Id}", this);
            }

            return null;
        }

        private static object GetFieldOrProperty(object initial, string fieldOrProperty, Type type, out Type fieldOrPropertyType)
        {
            var field = type.GetField(fieldOrProperty, Inherited);
            if (field != null)
            {
                fieldOrPropertyType = field.FieldType;
                return field.GetValue(initial);
            }

            var property = type.GetProperty(fieldOrProperty, Inherited);
            if (property != null)
            {
                fieldOrPropertyType = property.PropertyType;
                return property.GetValue(initial);
            }

            fieldOrPropertyType = null;
            return null;
        }

        private string Format(object fieldOrProperty)
        {
            if (string.IsNullOrEmpty(Formatting))
            {
                return fieldOrProperty.ToString();
            }

            return Formatter.Format(fieldOrProperty);

            var date = (DateTime) fieldOrProperty;
            if (date == null)
            {
                throw new ArgumentException($"Unable to parse {fieldOrProperty} as DateTime");
            }

            return date.ToString(Formatting);
        }
    }

    [SitecoreType(true, "{70846EB9-92EF-41A5-A556-D926BCFB3668}")]
    public class HTMLTableColumnFormatter : BaseItem, ITableColumnFormatter {
        public string Format(object fieldOrProperty)
        {
            throw new NotImplementedException();
        }
    }

    [SitecoreType(true, "{0408DB66-F660-48E0-81A0-7499BF423143}")]
    public class DateTimeTableColumnFormatter : BaseItem, ITableColumnFormatter {
        public string Format(object fieldOrProperty)
        {
            throw new NotImplementedException();
        }
    }

    [SitecoreType(true, "{A29D959E-98E1-433F-A309-A60E012DB138}")]
    public interface ITableColumnFormatter
    {
        string Format(object fieldOrProperty);
    }
}

As it stands right now, the NotImplementedException is not thrown. I would like Sitecore and GlassMapper to enter the appropriate method. Is there an example of how to do this?

1 Answer 1

2

look at inferred types http://www.glass.lu/Mapper/Sc/Tutorials/Tutorial17, this will allow you to get a more specific type from a base type.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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