public IDictionary <String, Object> Serialize(Object obj, JavaScriptSerializer serializer, HashSet <String> index, RestSerializationDepth depth, RestSerializationDepth toDepth, bool inList) { Type runtimeType = obj.GetType(); // Create a dictionary and add the rest uri as a default property IDictionary <String, Object> result = new Dictionary <String, Object>(); // If we have been asked to serialise nothing, return the empty result if (toDepth == RestSerializationDepth.None) { return(result); } if (obj is Proxy) { String context = String.Join(".", runtimeType.Namespace.Split('.').Skip(1)); object rawId = runtimeType.GetProperty("Id", BindingFlags.Public | BindingFlags.Instance).GetValue(obj); String identifier = rawId == null || (rawId.GetType().In(typeof(int), typeof(long), typeof(byte), typeof(short)) && rawId.ConvertTo <long>() == 0) ? "" : rawId.ConvertTo <String>(); String uri = String.Concat(context, "/", runtimeType.Name, "/", identifier); if (index.Contains(uri)) { return(null); } result.Add("uri", uri); index.Add(uri); } // Add each public instance property to the dictionary PropertyInfo[] properties = runtimeType.GetProperties(BindingFlags.Public | BindingFlags.Instance); List <string> toIgnore = Ignore.ContainsKey(obj.GetType()) ? Ignore[obj.GetType()] : new List <string>(); List <string> toInclude = Include.ContainsKey(obj.GetType()) ? Include[obj.GetType()] : new List <string>(); Dictionary <string, RestSerializationDepth> listDepths = NamedListsResolveToDepth.ContainsKey(obj.GetType()) ? NamedListsResolveToDepth[obj.GetType()] : new Dictionary <string, RestSerializationDepth>(); foreach (PropertyInfo property in properties.Where(prop => prop.CanRead && !toIgnore.Contains(prop.Name) && (toInclude.Count == 0 || prop.Name == "Id" || toInclude.Contains(prop.Name)))) { // Exclude members that are marked as non-serialized if (!property.GetCustomAttributes().OfType <NonSerializedAttribute>().Any()) { if ((property.PropertyType.IsGenericType && property.PropertyType.GetGenericTypeDefinition() == typeof(Collection <>)) || property.PropertyType.IsArray) { // Collections are (by default) serialized for root objects only if ((!inList && depth <= _listsAtDepth && depth <= toDepth && !listDepths.ContainsKey(property.Name)) || (listDepths.ContainsKey(property.Name) && listDepths[property.Name] != RestSerializationDepth.None)) { RestSerializationDepth listDepth = listDepths.ContainsKey(property.Name) ? listDepths[property.Name] : _listToDepth; result[property.Name] = (property.GetValue(obj) as IEnumerable).OfType <Object>().Select(element => this.Serialize(element, serializer, index, RestSerializationDepth.Root, listDepth, true)); } } else if (typeof(Consensus.Common.ICodeModel).IsAssignableFrom(property.PropertyType)) { // Code Models are serialized on root and child objects. if (!inList && depth < toDepth && depth != RestSerializationDepth.None) { result[property.Name] = this.Serialize(property.GetValue(obj), serializer, index, RestSerializationDepth.None, toDepth, inList); } } else if (this.SupportedTypes.Contains(property.PropertyType)) { // Other models are serialized on root and child objects. if (depth < toDepth && depth != RestSerializationDepth.None) { if (depth == RestSerializationDepth.Root) { result[property.Name] = this.Serialize(property.GetValue(obj), serializer, index, RestSerializationDepth.Child, toDepth, inList); } else if (depth == RestSerializationDepth.Child) { result[property.Name] = this.Serialize(property.GetValue(obj), serializer, index, RestSerializationDepth.GrandChild, toDepth, inList); } } } else if (property.PropertyType.IsEnum) { // Native property types are serialized on all objects result[property.Name] = property.GetValue(obj).ToString(); } else if (property.PropertyType == typeof(DateTime) || property.PropertyType == typeof(DateTime?)) { DateTime?value = property.GetValue(obj).ConvertTo <DateTime?>(); if (value.HasValue) { result[property.Name] = value.Value.ToString("dd MMMM yyyy HH:mm:ss"); } else { result[property.Name] = null; } } else { result[property.Name] = property.GetValue(obj); } } } return(result); }