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?