Reputation: 671
We are using Glass Mapper with Sitecore, with our models we can get the values of sitecore fields. But I want to easily get the sitecore fields(sitecore field type) by using the model without hardcoding any strings (when using GetProperty()
, you need the property name string ) into the method.
So I wrote this thing to achieve this, however I am not happy with 2 types need to be passed in when using it since it looks awful when you have a long model identifier.
public static string SitecoreFieldName<T, TU>(Expression<Func<TU>> expr)
{
var body = ((MemberExpression)expr.Body);
var attribute = (typeof(T).GetProperty(body.Member.Name).GetCustomAttributes(typeof(SitecoreFieldAttribute), false)[0]) as SitecoreFieldAttribute;
return attribute.FieldName;
}
The most ideal way is be able to get it like this Model.SomeProperty.SitecoreField()
. However I can't figure out how to do the refection from there. Because that can will be a extension for any type.
Thanks!
Upvotes: 3
Views: 2222
Reputation: 8877
public static string SitecoreFieldName<TModel>(Expression<Func<TModel, object>> field)
{
var body = field.Body as MemberExpression;
if (body == null)
{
return null;
}
var attribute = typeof(TModel).GetProperty(body.Member.Name)
.GetCustomAttributes(typeof(SitecoreFieldAttribute), true)
.FirstOrDefault() as SitecoreFieldAttribute;
return attribute != null
? attribute.FieldName
: null;
}
Note that I put inherit=true
on the GetCustomAttributes
method call.
Otherwise inherited attributes are ignored.
Upvotes: 6
Reputation: 671
I don't understand why my question got down-voted. So you think it's perfect code already?
With help of another senior developer, I improved it today so it doesn't need 2 types any more and much clearer on usage syntax:
public static Field GetSitecoreField<T>(T model, Expression<Func<T, object>> expression) where T : ModelBase
{
var body = ((MemberExpression)expression.Body);
var attributes = typeof(T).GetProperty(body.Member.Name).GetCustomAttributes(typeof(SitecoreFieldAttribute), false);
if (attributes.Any())
{
var attribute = attributes[0] as SitecoreFieldAttribute;
if (attribute != null)
{
return model.Item.Fields[attribute.FieldName];
}
}
return null;
}
and I can just call it by doing this:
GetSitecoreField(Container.Model<SomeModel>(), x => x.anyField)
Hope it helps anyone who is using Glass Mapper with Sitecore and want to get current sitecore field from model property.
Upvotes: 1