Copied to clipboard

Flag this post as spam?

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


  • Casper 70 posts 308 karma points
    Aug 22, 2016 @ 17:23
    Casper
    0

    Umbraco property type alias of the property beeing processed

    Hi,

    Is there a smart way to get the umbraco property type alias of the property beeing processed?

        public override object ProcessValue()
        {
            // get umbraco property alias
        }
    

    I have something working, but it is very inelegant - here a snippet from my "Ditto poco":

    [UmbracoContentTypeAliasAttributes(value: "heatProviderType")]
    [PopulatedDropDownProcessor]
    public UmbracoDropDown HeatProviderType { get; set; }
    

    Here I created a custom attribute where the property type alias can be pulled from. I could have gone with using an UmbracoPropertyAttribute but was not sure if it would trigger unnecessary overhead?

    Now, when I wan't to read out the attribute value, here is how I do it:

    var propertyName = string.Empty;
    foreach (var attribute in Context.PropertyDescriptor.Attributes)
    {
        var umbracoContentTypeAliasAttribute = attribute as UmbracoContentTypeAliasAttributes;
        if (umbracoContentTypeAliasAttribute != null)
            propertyName = umbracoContentTypeAliasAttribute.Value;
        if (!string.IsNullOrEmpty(propertyName))
            break;
    }
    

    So all boils down to these two guys:

    • Can Ditto in some smart way provide me with the alias i need, without doing any specialized stuff?

    • Would using UmbracoPropertyAttributes create unnecessary overhead, or is it canceled out due to processing the property myself?

    Thanks,

    //casper

  • Lee Kelleher 4020 posts 15802 karma points MVP 13x admin c-trib
    Aug 24, 2016 @ 08:35
    Lee Kelleher
    100

    Hi Casper,

    Using the [UmbracoProperty] attribute will attempt to get the value, it wont get you any additional data about the Umbraco property itself.

    I'm not too sure what your processor code is trying to do with the UmbracoContentTypeAliasAttributes. Am I correct in thinking that you want to pass in a string? or that the only way you've been able to pass in the property's alias so far?

    Ditto doesn't offer this functionality out-of-the-box.


    I've taken the liberty of writing up an example Processor to show how I'd go about doing it...

    using Umbraco.Core.Models;
    
    namespace Our.Umbraco.Ditto
    {
        public class UmbracoPropertyTypeAlias : DittoProcessorAttribute
        {
            public UmbracoPropertyTypeAlias()
            { }
    
            public UmbracoPropertyTypeAlias(string propertyName)
            {
                PropertyName = propertyName;
            }
    
            public string PropertyName { get; set; }
    
            public override object ProcessValue()
            {
                // check that the value is an Umbraco content node
                var content = this.Value as IPublishedContent;
                if (content != null)
                {
                    // try to get the property's name from the POCO property, otherwise try fall back on the name passed in
                    var propName = this.Context.PropertyDescriptor != null ? this.Context.PropertyDescriptor.Name : string.Empty;
                    var umbracoPropertyName = this.PropertyName ?? propName;
    
                    if (!string.IsNullOrWhiteSpace(umbracoPropertyName))
                    {
                        // get the property "object", (rather than the value)
                        var property = content.GetProperty(umbracoPropertyName);
                        if (property != null)
                        {
                            // return the property's type alias
                            return property.PropertyTypeAlias;
                        }
                    }
                }
    
                return null;
            }
        }
    }
    

    Then in your POCO, you can add the attribute to your property...

    [UmbracoPropertyTypeAlias]
    [PopulatedDropDownProcessor]
    public UmbracoDropDown HeatProviderType { get; set; }
    

    Then in your PopulatedDropDownProcessor code, the this.Value property should be a string containing the Umbraco property's type alias.

    I haven't tested any of this... so if it doesn't work first time, you'll need to tinker around with it. But let me know how you get on.

    I hope this helps?

    Cheers,
    - Lee

  • Casper 70 posts 308 karma points
    Aug 24, 2016 @ 11:12
    Casper
    1

    Hi Lee,

    Thank you for replying. By reading the question again I can tell my stress level was a bit high - My brain went awall...on itself ;)

    What i wanted was just to pass a string parameter(my umbraco doc type property alias) to my processor in order to get that field when processing.

    I removed my custom attrubute, added a contructor and POW - now less code (no custom attribute, no reading out the value of that custom attribute) and same result.

    Before:

    [UmbracoPropertyTypeAlias(value: "prop")]
    [PopulatedDropDownProcessor]
    

    Now:

    [PopulatedDropDownProcessor("prop")]
    

    The point of my processor is to take an umbraco doctype property that in the back-end i driven by "Umbraco.DropDown" and then convert the property into an object holding its current value along with possible options:

    Here is the result so far:

    public class UmbracoDropDown
    {
        public int Id { get; set; }
        public string Alias { get; set; }
        public string Value { get; set; }
        public List<string> Options { get; set; } = new List<string>();
    }
    
    public class PopulatedDropDownProcessor : DittoProcessorAttribute
    {
        private string _propertyName = string.Empty;
    
        public PopulatedDropDownProcessor(string propertyName) 
        {
            _propertyName = propertyName;         
        }
    
        public override object ProcessValue()
        {
            try
            {
                var propertyName = _propertyName;
                if (!string.IsNullOrEmpty(propertyName))
                    return GetDropDown(Context.Content, propertyName);
                return null;
            }
            catch (Exception)
            {
                return null;
            }
        }
    
        const string UMBRACO_DROPDOWN = "Umbraco.DropDown";
    
        private IDataTypeService _ds = ApplicationContext.Current.Services.DataTypeService;
        private IContentService _cs = ApplicationContext.Current.Services.ContentService;
    
        internal UmbracoDropDown GetDropDown(IPublishedContent publishedContent, string propertyName)
        {
            var cachedModelKey = $"{UMBRACO_DROPDOWN}{propertyName}{publishedContent.Id}";
            var cachedModel = HttpRuntime.Cache[cachedModelKey];
            if (cachedModel == null)
            {
                var content = _cs.GetById(publishedContent.Id);
                var dropDown = 
                    content?.
                    Properties
                    .First(x => x.PropertyType.PropertyEditorAlias == UMBRACO_DROPDOWN && 
                        x.Alias.InvariantEquals(propertyName));
                if (dropDown == null)
                    return null;
                var model = new UmbracoDropDown()
                {
                    Id = dropDown.Id,
                    Alias = dropDown.Alias,
                    Value = _ds.GetPreValueAsString(content.GetValue<int>(dropDown.PropertyType.Alias)),
                    Options = _ds.GetPreValuesByDataTypeId(dropDown.PropertyType.DataTypeDefinitionId).ToList()
                };
                HttpRuntime.Cache.Add(
                    cachedModelKey, 
                    model, 
                    null, 
                    DateTime.Now.AddMinutes(60), 
                    System.Web.Caching.Cache.NoSlidingExpiration, 
                    System.Web.Caching.CacheItemPriority.High, 
                    null);
                return model;
            }
            else
            {
                return cachedModel as UmbracoDropDown;
            }
        }
    
    }
    

    Thanks for pointing me in the right direction,

    //casper

Please Sign in or register to post replies

Write your reply to:

Draft