【问题标题】:JSON serialization using recursion and reflection. (Issue with arrays)使用递归和反射的 JSON 序列化。 (数组问题)
【发布时间】:2020-06-09 01:22:20
【问题描述】:

我目前正在尝试制作自己的 JSON 序列化方法,但是当我调用像这样调用的“序列化”方法时,我遇到了数组问题:

string person = MyJsonConverter.Serialize(new Clerk("Alexander", 1999, new List<string> { "Computer Science", "Web Developer" }));
Console.WriteLine(person);

这会产生以下内容:

{"Skills": ["Capacity": "4", "Count": "2"], "Name": "Alexander", "YearOfBirth": "1999"}

但应该产生这个:

{"Skills": ["Computer Science", "Web Developer"], "Name": "Alexander", "YearOfBirth": "1999"}

我需要帮助的方法是这个,我不完全确定我做错了什么,但由于某种原因,它需要数组的属性而不是数组的值。

public static string Serialize(object obj)
{
    StringBuilder stringBuilder = new StringBuilder();

    IEnumerable<PropertyInfo> properties = obj.GetType().GetProperties().Where(p => p.GetIndexParameters().Length == 0);

    if (typeof(IEnumerable).IsAssignableFrom(obj.GetType()))
        stringBuilder.Append($"[");
    else
        stringBuilder.Append($"{{");

    foreach (var property in properties)
        if (property.PropertyType.IsPrimitive || property.PropertyType == typeof(string))
            stringBuilder.Append($"\"{property.Name}\": \"{property.GetValue(obj)}\", ");
        else
            stringBuilder.Append($"\"{property.Name}\": {Serialize(property.GetValue(obj))}, ");

    string temp = stringBuilder.ToString().Trim().Remove(stringBuilder.ToString().Length - 2);

    stringBuilder.Clear();
    stringBuilder.Append(temp);

    if (typeof(IEnumerable).IsAssignableFrom(obj.GetType()))
        stringBuilder.Append($"]");
    else
        stringBuilder.Append($"}}");

    return stringBuilder.ToString();
}

非常感谢所有帮助。

【问题讨论】:

  • 是否需要您编写自己的解析器?您可以使用 newtonsoft nuget 并收工。
  • @Rafa 是的,因为它是为了分配。我已经知道 JsonConvert 等......但我必须为这个任务自己做。
  • typeof(IEnumerable&lt;object&gt;).IsAssignableFrom(obj.GetType()) terrible idea as IEnumerable&lt;object&gt; is not assgnable from IEnumerable&lt;SomeValueType&gt;
  • 我认为您的代码的问题在于它按预期工作。对于列表,您需要遍历其元素。同样对于嵌套对象,您需要以递归方式调用 Serialize
  • @AlexanderBruun 点击第一个链接

标签: c# .net json recursion reflection


【解决方案1】:

我通过这样做解决了它:

public static string Serialize(object obj)
{
    StringBuilder stringBuilder = new StringBuilder();

    IEnumerable<PropertyInfo> properties = obj.GetType().GetProperties();

    if (!obj.GetType().IsPrimitive && obj.GetType() != typeof(string))
    {
        bool isArray = typeof(IEnumerable).IsAssignableFrom(obj.GetType()) ? true : false;

        if (isArray)
            stringBuilder.Append($"[");
        else
            stringBuilder.Append($"{{");

        if (!isArray)
            foreach (var property in properties)
                if (property.PropertyType.IsPrimitive || property.PropertyType == typeof(string))
                    stringBuilder.Append($"\"{property.Name}\": \"{property.GetValue(obj)}\", ");
                else
                    stringBuilder.Append($"\"{property.Name}\": {Serialize(property.GetValue(obj))}, ");
        else
            foreach (var i in obj as IEnumerable)
                if (i.GetType().IsPrimitive || i.GetType() == typeof(string))
                    stringBuilder.Append($"\"{i}\", ");
                else
                    stringBuilder.Append($"{Serialize(i)}, ");

        stringBuilder.Remove(stringBuilder.ToString().Length - 2, 2);

        if (isArray)
            stringBuilder.Append($"]");
        else
            stringBuilder.Append($"}}");
    }
    else
        stringBuilder.Append(obj.ToString());

    return stringBuilder.ToString();
}

它可能不是最漂亮的,但它确实有效。

我仍然愿意接受建议。

【讨论】:

    猜你喜欢
    • 2011-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-03
    相关资源
    最近更新 更多