Пример #1
0
        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();
        }
Пример #2
0
        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("}");
        }