public static void WriteComplexQueryStringProperties(string typeName, TextWriter writer, object instance) { var i = 0; if (PropertyWriters != null) { var config = JsConfig <T> .GetPropertyConfigs(); var typedInstance = (T)instance; var len = PropertyWriters.Length; for (var index = 0; index < len; index++) { var propertyWriter = PropertyWriters[index]; if (propertyWriter.shouldSerialize != null && !propertyWriter.shouldSerialize(typedInstance)) { continue; } var propertyValue = instance != null?propertyWriter.GetterFn(typedInstance) : null; if (propertyWriter.propertySuppressDefaultAttribute && Equals(propertyWriter.DefaultValue, propertyValue)) { continue; } if ((propertyValue == null || propertyWriter.propertySuppressDefaultConfig && Equals(propertyWriter.DefaultValue, propertyValue)) && !Serializer.IncludeNullValues) { continue; } if (JsConfig.ExcludePropertyReferences != null && JsConfig.ExcludePropertyReferences.Contains(propertyWriter.propertyReferenceName)) { continue; } if (i++ > 0) { writer.Write('&'); } var propertyValueType = propertyValue?.GetType(); if (propertyValueType != null && propertyValueType.IsUserType() && !propertyValueType.HasInterface(typeof(IEnumerable))) { //Nested Complex Type: legal_entity[dob][day]=1 var prefix = $"{typeName}[{propertyWriter.GetPropertyName(config)}]"; var props = propertyValueType.GetSerializableProperties(); for (int j = 0; j < props.Length; j++) { var pi = props[j]; var pValue = pi.GetValue(propertyValue, TypeConstants.EmptyObjectArray); if (pValue == null && !Serializer.IncludeNullValues) { continue; } if (j > 0) { writer.Write('&'); } writer.Write(prefix); writer.Write('['); writer.Write(GetPropertyName(pi.Name, config)); writer.Write("]="); if (pValue == null) { writer.Write(JsonUtils.Null); } else { JsvWriter.GetWriteFn(pValue.GetType())(writer, pValue); } } } else { writer.Write(typeName); writer.Write('['); writer.Write(propertyWriter.GetPropertyName(config)); writer.Write("]="); if (propertyValue == null) { writer.Write(JsonUtils.Null); } else { propertyWriter.WriteFn(writer, propertyValue); } } } } }
public static void WriteQueryString(TextWriter writer, object instance) { try { JsState.QueryStringMode = true; var config = JsConfig <T> .GetPropertyConfigs(); var i = 0; var typedInstance = (T)instance; foreach (var propertyWriter in PropertyWriters) { var propertyValue = propertyWriter.GetterFn(typedInstance); if (propertyValue == null) { continue; } if (i++ > 0) { writer.Write('&'); } var propertyType = propertyValue.GetType(); var strValue = propertyValue as string; var isEnumerable = strValue == null && !propertyType.IsValueType && propertyType.HasInterface(typeof(IEnumerable)); if (QueryStringSerializer.ComplexTypeStrategy != null) { var nonEnumerableUserType = !isEnumerable && (propertyType.IsUserType() || propertyType.IsInterface); if (nonEnumerableUserType || propertyType.IsOrHasGenericInterfaceTypeOf(typeof(IDictionary <,>))) { if (QueryStringSerializer.ComplexTypeStrategy(writer, propertyWriter.GetPropertyName(config), propertyValue)) { continue; } } } Serializer.WritePropertyName(writer, propertyWriter.GetPropertyName(config)); writer.Write('='); if (strValue != null) { writer.Write(strValue.UrlEncode()); } else if (!isEnumerable) { propertyWriter.WriteFn(writer, propertyValue); } else { //Trim brackets in top-level lists in QueryStrings, e.g: ?a=[1,2,3] => ?a=1,2,3 using (var ms = MemoryStreamFactory.GetStream()) { var enumerableWriter = new StreamWriter(ms); //ms disposed in using propertyWriter.WriteFn(enumerableWriter, propertyValue); enumerableWriter.Flush(); var output = ms.ReadToEnd(); output = output.Trim(ArrayBrackets); writer.Write(output); } } } } finally { JsState.QueryStringMode = false; } }
public static void WriteProperties(TextWriter writer, object instance) { if (instance == null) { writer.Write(JsWriter.EmptyMap); return; } var valueType = instance.GetType(); if (PropertyWriters != null && valueType != typeof(T) && !typeof(T).IsAbstract) { WriteLateboundProperties(writer, instance, valueType); return; } if (typeof(TSerializer) == typeof(JsonTypeSerializer) && JsState.WritingKeyCount > 0) { writer.Write(JsWriter.QuoteChar); } writer.Write(JsWriter.MapStartChar); var i = 0; if (WriteTypeInfo != null || JsState.IsWritingDynamic) { if (JsConfig.PreferInterfaces && TryWriteSelfType(writer)) { i++; } else if (TryWriteTypeInfo(writer, instance)) { i++; } JsState.IsWritingDynamic = false; } if (PropertyWriters != null) { var config = JsConfig <T> .GetPropertyConfigs(); var typedInstance = (T)instance; var len = PropertyWriters.Length; for (int index = 0; index < len; index++) { var propertyWriter = PropertyWriters[index]; if (propertyWriter.shouldSerialize?.Invoke(typedInstance) == false) { continue; } var dontSkipDefault = false; if (propertyWriter.shouldSerializeDynamic != null) { var shouldSerialize = propertyWriter.shouldSerializeDynamic(typedInstance, propertyWriter.GetPropertyName(config)); if (shouldSerialize.HasValue) { if (shouldSerialize.Value) { dontSkipDefault = true; } else { continue; } } } var propertyValue = propertyWriter.GetterFn(typedInstance); if (!dontSkipDefault) { if (!propertyWriter.ShouldWriteProperty(propertyValue, config)) { continue; } if (config.ExcludePropertyReferences?.Contains(propertyWriter.propertyReferenceName) == true) { continue; } } if (i++ > 0) { writer.Write(JsWriter.ItemSeperator); } Serializer.WritePropertyName(writer, propertyWriter.GetPropertyName(config)); writer.Write(JsWriter.MapKeySeperator); if (typeof(TSerializer) == typeof(JsonTypeSerializer)) { JsState.IsWritingValue = true; } try { if (propertyValue == null) { writer.Write(JsonUtils.Null); } else { propertyWriter.WriteFn(writer, propertyValue); } } finally { if (typeof(TSerializer) == typeof(JsonTypeSerializer)) { JsState.IsWritingValue = false; } } } } writer.Write(JsWriter.MapEndChar); if (typeof(TSerializer) == typeof(JsonTypeSerializer) && JsState.WritingKeyCount > 0) { writer.Write(JsWriter.QuoteChar); } }