Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Olie 11 posts 52 karma points
    Jun 27, 2018 @ 04:56
    Olie
    0

    Setting Complex Model Properties using custom IPropertyValueGetter

    Hi Andy,

    Thanks for writing this package! It's saved me tons of plumbing code!

    I tried to use the IPropertyValueGetter to set a non-primitive property on a model but it was never setting the property.

    The use case I have is converting a property that is either from the field (if exists - RJP Url Picker) otherwise fall back to the Url and Name of the content being mapped if the content has a template.

    The Property...

    [PropertyMapping(PropertyValueGetter = typeof(PromotionLinkPropertyValueGetter))]
    public MyViewModels.Link Link { get; set; }
    

    My Property Getter...

    public class PromotionLinkPropertyValueGetter : IPropertyValueGetter
    {
        public object GetPropertyValue(IPublishedContent content, string alias, bool recursive)
        {
            var rjpLinkCollection = content.GetPropertyValue<IEnumerable<RJP.MultiUrlPicker.Models.Link>>(alias);
            var link = rjpLinkCollection?.FirstOrDefault()?.ToMyLink();
    
            if (link != null)
            {
                return link;
            }
            link = content.TemplateId > 0 ? content.Map<MyViewModels.Link>() : null;
            return link;
        }
    }
    

    I pulled the code for UmbracoMapper and found due to the destination property being a not simple type it was running a check to see if it was a single or collection of IPublishedContent, I added another check to see if the IPropertyValueGetter was returning a value of type required by the target property, and if so just set that as the value. https://github.com/AndyButland/UmbracoMapper/blob/master/Zone.UmbracoMapper/UmbracoMapper.cs#L1130

    if (value is IPublishedContent)
    {
        typeof (UmbracoMapper)
            .GetMethod("MapIPublishedContent", BindingFlags.NonPublic | BindingFlags.Instance)
            .MakeGenericMethod(property.PropertyType)
            .Invoke(this, new object[] {(IPublishedContent) value, property.GetValue(model)});
    }
    else if (value is IEnumerable<IPublishedContent> && property.PropertyType.GetInterface("IEnumerable") != null)
    {
        var collectionPropertyType = GetGenericCollectionType(property);
        typeof (UmbracoMapper)
            .GetMethod("MapCollectionOfIPublishedContent", BindingFlags.NonPublic | BindingFlags.Instance)
            .MakeGenericMethod(collectionPropertyType)
            .Invoke(this, new object[] {(IEnumerable<IPublishedContent>)value, property.GetValue(model), null});                            
    }
    else if (value.GetType().IsAssignableFrom(property.PropertyType))
    {
        property.SetValue(model, value);
    }
    

    Adding the last 4 lines seems to fix it for me.

    Thanks again!
    Olie

    P.S. I thought IMapFromAttribute appeared to be a way to implement custom mapping, but that does not have access to the IPublishedContent, (which I need), only has access to the property value.

  • Andy Butland 362 posts 1954 karma points MVP 4x c-trib
    Jun 27, 2018 @ 12:33
    Andy Butland
    0

    Hi Ollie

    Thanks for the suggestions. Looks to me sensible so I'll have a look at adding this to the package shortly (am on holiday for another 10 days or so, so might get to it after that if you don't see an update shortly).

    The package has had a few embellishments over the years so there's probably more than one way to do things. Initially I'd probably have tackled what you were looking to do via registering a custom mapping, so you might find that approach works too.

    Cheers

    Andy

  • Andy Butland 362 posts 1954 karma points MVP 4x c-trib
    Jun 29, 2018 @ 13:08
    Andy Butland
    0

    If you try the latest version - 2.0.6 - you should find this additional mapping feature you provided is available.

    Cheers

    Andy

  • Olie 11 posts 52 karma points
    Jul 03, 2018 @ 23:36
    Olie
    0

    Awesome thanks a bunch Andy!

    Cheers, Olie

Please Sign in or register to post replies

Write your reply to:

Draft