November Happy Hour will be moved to Thursday December 5th.

BUG? GetPropertySettings for embedded blocks don't work

Vote:
 

I have a page model with an embedded block

[ContentType(GUID = "...")]
public class StandardPage : PageData {
    public virtual MediaBlock MediaBlock { get; set; }
}

[ContentType(DisplayName = "Media block", GUID = "...", Description = "")]
public class MediaBlock : BlockData {
    public virtual MediaReference Media { get; set; }
}

When I try to get the property settings for this property, I get nothing back.

IContent pageContent=...;
//get block property
IContentData block = pageContent.Property.Single(p=>p.Name=="MediaBlock") as IContentData;
//get settings for block property Media
var settings = block.GetPropertySettings("Media");

When inspecting the GetPropertySettings extension method, it invokes the RuntimeModelExtensions.GetOriginalType() method to calculate the underlying content type.

When we have a block we don't get the typeof(MediaBlock) as expected, but instead typeof(PropertyBlock) that don't have any property settings.

It's not supposed to work like that huh?

The following modified method works for me

public static TPropertySettings GetPropertySettings(IContentData contentData, string propertyName) where TPropertySettings : IPropertySettings {
    var settingsType = typeof(TPropertySettings);
    //Handle property blocks
    var propertyBlock = contentData as IPropertyBlock;
    if (propertyBlock != null) {
        contentData = propertyBlock.Block;
    }
    var originalType = contentData.GetOriginalType();
    var propertySettingsResolver = ServiceLocator.Current.GetInstance();
   return (TPropertySettings)propertySettingsResolver.GetSettings(settingsType, originalType, propertyName);
}
#140356
Oct 16, 2015 13:57
Vote:
 

GetPropertySettings was intended for the typed model (pageContent.MediaBlock.GetPropertySettings<>()) rather than the underlying property (PropertyBlock). PropertySettingsResolver was intended to be a raw version for untyped access which is what we use internally at EPi since we have no acces to the typed model.

#140937
Nov 04, 2015 11:31
Vote:
 

Do you have a more suitable way to get the Property as the correct type without getting a proxy type back?

The method below only returns the proxy variant, not the real property value type

pageContent.Property.Single(p=>p.Name=="MediaBlock") as IContentData;


 

#140963
Edited, Nov 05, 2015 9:44
Vote:
 

If you cast it to IPropertyBlock instead you have a BlockType property.

#140964
Nov 05, 2015 9:58
Vote:
 

I think the main confusion about this issue is that a IContentData.Property only contains PropertyData objects, and an embedded Block on a page is not a PropertyData object. To include it in the Property collection you need to wrap it in a PropertyBlock<T> class and when iterating the properties and asking for property settings for a PropertyBlock<T> it does not look beyond the PropertyBlock<T> class.

I ended up with the following solution to get the concrete container that I could ask for property settings.

//Getting the property settings for item "MediaBlock.Media" on page
IContentData pageContent=...;
var propertyBlock = pageContent.Property.Single(p=>p.Name=="MediaBlock") as IPropertyBlock;
var block = propertyBlock.Block;
var settings = block.GetPropertySettings<PropertyMediaSettings>("Media");

I would suggest though that you added support for the GetPropertySettings method to work with IPropertyBlock instances since you can only set property settings on the block type itself (not the PropertyBlock<T> type). This support should allow calling the methods below yielding the same result (Both IPropertyBlock and BlockData is IContentData and should behave in the same manner in this case).

var settings1 = propertyBlock.GetPropertySettings<PropertyMediaSettings>("Media");
var settings2 = propertyBlock.Block.GetPropertySettings<PropertyMediaSettings>("Media");
#140974
Edited, Nov 05, 2015 12:55
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.