public static IEnumerable <CustomRatingProgress> CustomRatingsForUser(string szUser) { if (szUser == null) { throw new ArgumentNullException(nameof(szUser)); } Profile pf = Profile.GetUser(szUser); // build a map of all histogrammable values for naming List <HistogramableValue> lst = new List <HistogramableValue>(LogbookEntryDisplay.HistogramableValues); foreach (CustomPropertyType cpt in CustomPropertyType.GetCustomPropertyTypes()) { HistogramableValue hv = LogbookEntryDisplay.HistogramableValueForPropertyType(cpt); if (hv != null) { lst.Add(hv); } } Dictionary <string, HistogramableValue> d = new Dictionary <string, HistogramableValue>(); foreach (HistogramableValue hv in lst) { d[hv.DataField] = hv; } // MUST use the pf.GetPreferenceForKey with one argument because you need the serialize/deserialize to get the correct type conversion. IEnumerable <CustomRatingProgress> rgProgressForUser = pf.GetPreferenceForKey <IEnumerable <CustomRatingProgress> >(szPrefKeyCustomRatings); if (rgProgressForUser == null) { return(Array.Empty <CustomRatingProgress>()); } foreach (CustomRatingProgress crp in rgProgressForUser) { crp.Username = szUser; foreach (CustomRatingProgressItem crpi in crp.ProgressItems) { crpi.FieldFriendlyName = d.TryGetValue(crpi.FieldName, out HistogramableValue hv) ? hv.DataName : crpi.FieldName; } List <CustomRatingProgressItem> lstItems = new List <CustomRatingProgressItem>(crp.ProgressItems); lstItems.Sort((crpi1, crpi2) => { return(crpi1.FARRef.CompareCurrentCultureIgnoreCase(crpi2.FARRef)); }); crp.ProgressItems = lstItems; } return(rgProgressForUser); }