Property Type Conversion

Vote:
 

Hello,

I'm trying to take a property type on an existing and used content type and convert it's data type to a newly created property type.  I have created the backing type and the Model for the backing type that is used below:

[PropertyDefinitionTypePlugIn(Description = "A property for additional location entries", DisplayName = "Additional Locations")]
    public class PropertyAdditionalLocations : PropertyLongString
    {
        public override Type PropertyValueType
        {
            get { return typeof (List); }
        }

        public override object SaveData(PropertyDataCollection properties)
        {
            return LongString;
        }

        public override object Value
        {
            get
            {
                var value = base.Value as string;
                var serializer = new JavaScriptSerializer();

                if (value == null)
                {
                    return new List();
                }
                
                return serializer.Deserialize(value, typeof (List));
            }
            set
            {
                if (value is List)
                {
                    var serializer = new JavaScriptSerializer();
                    base.Value = serializer.Serialize(value);
                }
                else
                {
                    base.Value = value;
                }
            }
        }
    }
public class AdditionalLocation
    {
        public string LocationDisplayName { get; set; }
        public string Addressline1 { get; set; }
        public string Addressline2 { get; set; }
        public string City { get; set; }
        public string StateOrProvince { get; set; }
        public string Zip { get; set; }
        public string Phonenumber { get; set; }
        public string Faxnumber { get; set; }
        public string HoursofOperation { get; set; }
        public string PhoneHours { get; set; }
        public string ContactEmail { get; set; }
        public bool CustomerReviewEnabled { get; set; }
        public string Note { get; set; }
        public virtual string StateJurisdiction { get; set; }

        public override string ToString()
        {
            var ser = new JavaScriptSerializer();
            return ser.Serialize(this);
        }
    }


Previously, this property was created and stored with an obsoleted third party method (MultiProperty) which in CMS 9 is no longer working because of the absense of a required DLL that is referenced that was removed.  In any case, we want to move AWAY from using this and continue forward with our dojo widget editors and property backing types as they are clean and work great within epi's layed out framework.

The issue i'm having is that i'm not sure how to get the old value that is stored in this property to convert and save into the new value we expect and want (as stated above in the backing type and model - a list of the AdditionalLocation object).

Creating a brand new property on a content type with this works GREAT and as expected and the values save fine.  What doesn't work is changing the backing type and property type on an existing property - the value WAS stored as an xml string so it does kind of "work" but obviously my Value function in the backing type errors because the "Json" isn't what it's expecting to push into the object type I want.

How and where do i implement code to tell episerver to convert the data (I can write the code to look at the old data and convert it into the new expected format easily) and save it for existing data so my property loads correctly with expected data?

Do i just have to write a scheduled job and parse this stuff?  I was hoping not to and that on initialization epi would find some area where i've written this code and convert the data?

Any help is appreciated, thank you!

#139317
Sep 29, 2015 21:37
Vote:
 

Another thought while writing this was that I could implement something in the Value override in the backing type that checks if the Deserialize works, if it doesn't (I know i'm dealing with old data at that point) I could write the conversion there to convert it to the expected value object.  And that way the value WILL load up correctly and then next time they publish will save correctly...  I'm not sure I like this though.  I am really hoping to hit this head on and have epi convert the data (with code i supply) when the site spins up and notices that the property definition has changed to a new type.

#139318
Sep 29, 2015 21:48
Vote:
 

I wound up using this (adding the conversion into the Value override in the get extension... I'm not sure how much I like this, but at least it will load the property up with the older XML stored data, and when they publish or save next time it will convert it.

[PropertyDefinitionTypePlugIn(Description = "A property for additional location entries", DisplayName = "Additional Locations")]
    public class PropertyAdditionalLocations : PropertyLongString
    {
        public override Type PropertyValueType
        {
            get { return typeof (List<AdditionalLocation>); }
        }

        public override object SaveData(PropertyDataCollection properties)
        {
            return LongString;
        }

        public override object Value
        {
            get
            {
                var value = base.Value as string;
                var serializer = new JavaScriptSerializer();

                if (value == null)
                {
                    return new List<AdditionalLocation>();
                }
                try
                {
                    return serializer.Deserialize(value, typeof(List<AdditionalLocation>));
                }
                catch
                {
                    // Old data manipulation - THIS SUCKS
                    XNamespace ns = "http://schemas.datacontract.org/2004/07/PhoenixCore.Extensions";
                    var locations = XDocument
                        .Parse(value)
                        .Descendants(ns + "GalleryAddLocationItem")
                        .Select(
                        x => new AdditionalLocation()
                        {
                            LocationDisplayName = XmlElementHelper.GetElement(x, ns, "LocationDisplayName"),
                            AddressLine1 = XmlElementHelper.GetElement(x, ns, "Addressline1"),
                            AddressLine2 = XmlElementHelper.GetElement(x, ns, "Addressline2"),
                            City = XmlElementHelper.GetElement(x, ns, "City"),
                            Note = XmlElementHelper.GetElement(x, ns, "Note"),
                            StateOrProvince = XmlElementHelper.GetElement(x, ns, "StateOrProvince"),
                            Zip = XmlElementHelper.GetElement(x, ns, "Zip"),
                            PhoneNumber = XmlElementHelper.GetElement(x, ns, "Phonenumber"),
                            FaxNumber = XmlElementHelper.GetElement(x, ns, "Faxnumber"),
                            HoursOfOperation = XmlElementHelper.GetElement(x, ns, "HoursofOperation"),
                            PhoneHours = XmlElementHelper.GetElement(x, ns, "PhoneHours"),
                            ContactEmail = XmlElementHelper.GetElement(x, ns, "ContactEmail"),
                            CustomerReviewEnabled = Convert.ToBoolean(XmlElementHelper.GetElement(x, ns, "CustomerReviewEnabled")),
                            StateJurisdiction = XmlElementHelper.GetElement(x, ns, "StateJurisdiction")
                        }).ToList();

                    return locations;
                }
            }
            set
            {
                if (value is List<AdditionalLocation>)
                {
                    var serializer = new JavaScriptSerializer();
                    base.Value = serializer.Serialize(value);
                }
                else
                {
                    base.Value = value;
                }
            }
        }
    }
#139320
Sep 29, 2015 23:09
* 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.