private void Write(Writer writer, object element, string elementName = null) { if (element == null) { writer.WriteValue(null); return; } var primitiveType = Nullable.GetUnderlyingType(element.GetType()); if (primitiveType != null) { element = Change.To(element, primitiveType); } if (element is CaseVariantString caseString) { var text = caseString.ChangeCase(writer.Settings.TextCase | TextCase.PreserveSpecialCharacters); writer.WriteValue(text); return; } if (element.GetType().IsValueType || SerializationUtilities.IsStringCompatible(element)) { writer.WriteValue(element); return; } if (element is PropertyMap map) { writer.WriteObjectStart(elementName ?? element.GetType().Name); foreach (var entry in map) { if (entry.Value != null) { writer.WritePropertyStart(entry.Key); Write(writer, entry.Value); writer.WritePropertyEnd(); } } writer.WriteObjectEnd(); return; } if (element is IEnumerable list) { var attr = element._GetAttribute <CollectionDataContractAttribute>(); var suggestedName = attr?.ItemName; writer.WriteCollectionStart(element.GetType().Name); foreach (var item in list) { Write(writer, item, suggestedName); } writer.WriteCollectionEnd(); return; } writer.WriteObjectStart(element.GetType().Name); foreach (var name in element._GetPropertyNames()) { var value = element._Get(name); if (value != null) { if (value is string text) { var caseAttr = element._GetAttribute <CaseVariantStringAttribute>(name); if (caseAttr != null) { value = (CaseVariantString)text; } } else if (value is IEnumerable items) { var caseAttr = element._GetAttribute <CaseVariantStringAttribute>(name); if (caseAttr != null) { value = items.Cast <object>().Select(x => (CaseVariantString)x?.ToString()); } } var memberAttr = element._GetAttribute <DataMemberAttribute>(name); var propertyName = memberAttr?.Name ?? name; writer.WritePropertyStart(propertyName); Write(writer, value); writer.WritePropertyEnd(); } } writer.WriteObjectEnd(); }
private void Write(TextWriter writer, object value) { if (value is CaseVariantString) { value = MakeCompatibleName(value.ToString()); // apenas ajusta o valor de acordo com a caixa e prossegue... } if (IsNull(value)) { writer.Write("null"); return; } if (IsNumeric(value)) { writer.Write(value); return; } if (SerializationUtilities.IsStringCompatible(value)) { writer.Write("\""); writer.Write(Toolset.Json.Escape(value.ToString())); writer.Write("\""); return; } if (value is bool) { writer.Write((bool)value ? 1 : 0); return; } if (value is DateTime) { writer.Write("\""); writer.Write(((DateTime)value).ToString("yyyy-MM-ddTHH:mm:sszzz")); writer.Write("\""); return; } if (value is NameCollection) { var items = (NameCollection)value; writer.Write("["); var comma = false; foreach (var item in items) { if (comma) { writer.Write(','); } comma = true; writer.Write("\""); writer.Write(Toolset.Json.Escape(item)); writer.Write("\""); } writer.Write("]"); return; } if (value is PropertyCollection) { var items = (PropertyCollection)value; writer.Write("{"); int count = 0; foreach (var item in items) { WriteProperty(writer, item.Name, item.Value, ref count); } writer.Write("}"); return; } if (value is IList) { var items = (IList)value; writer.Write("["); bool comma = false; foreach (var item in items) { if (comma) { writer.Write(","); } comma = true; Write(writer, item); } writer.Write("]"); return; } writer.Write("{"); var properties = ( from property in value.GetType().GetProperties() where !property.GetIndexParameters().Any() select property ).ToArray(); int propertyCount = 0; foreach (var property in properties) { var propertyValue = property.GetValue(value); if (IsEmpty(propertyValue)) { continue; } // Se a string for CaseVariantStringAttribute temos que converte-la para camelCase if (property.GetCustomAttributes().OfType <CaseVariantStringAttribute>().Any()) { propertyValue = (CaseVariantString)propertyValue.ToString(); } // Se estamos renderizando um link a sua coleção "Rel" precisa ser convertida para camelCase else if (value is Link) { if (property.Name == "Rel") { propertyValue = ((NameCollection)propertyValue) .Select(x => (CaseVariantString)x) .ToArray(); } } var propertyName = MakeCompatibleName(property.Name); WriteProperty(writer, propertyName, propertyValue, ref propertyCount); } writer.Write("}"); }