JSON反序列化" unhandy"字典

时间:2014-05-08 07:34:11

标签: c# dictionary json.net

我正在使用JSON.NET并且必须反序列化此结构。

"NameValue": [
    {
      "Name": "CONO",
      "Value": "001"
    },
    {
      "Name": "DIVI",
      "Value": "   "
    },
    {
      "Name": "LNCD",
      "Value": "DE"
    },
    {
      "Name": "CUNO",
      "Value": "#AT-VORL  "
    },
]

它是更大对象的一部分,我想反序列化为MyType。我可以拥有一个属性NameValue,它是一个类型为MyNameValue的对象列表,它有两个属性NameValue。但这只是一个字典的奇怪表示(名称永远不会重叠),所以我希望有一个更加方便的.NET字典。

如何使用我的课程中的属性来实现这一目标?

这是什么工作:

    private class JsonResponseRecord
    {
        public string RowIndex { get; set; }

        [JsonProperty(PropertyName = "NameValue")]
        public List<KeyValuePair<string, string>> Values { get; set; }
    }

但最终会得到一个KeyValuePairs列表,其中所有键都是null,而值正确填充。我想他会要求JSON有"Key"而不是"Name"


要明确说明:我希望将Dictionary<string, string>作为Values属性的类型:

    private class JsonResponseRecord
    {
        public string RowIndex { get; set; }

        [JsonProperty(PropertyName = "NameValue")]
        public Dictionary<string, string> Values { get; set; }
    }

3 个答案:

答案 0 :(得分:2)

首先对您发布的JSON字符串稍作修正。它应该是这样的:

var json =  {
       "NameValue": [
        {
          "Name": "CONO",
          "Value": "001"
        },
        {
          "Name": "DIVI",
          "Value": "   "
        },
        {
          "Name": "LNCD",
          "Value": "DE"
        },
        {
          "Name": "CUNO",
          "Value": "#AT-VORL  "
        }
      ]
    }

您可以使用JSON.NET内置Linq to JSON来获得所需内容。这是samlple代码:

    var jObject = JObject.Parse(json);
    var jsonResponseRecordObj = new JsonResponseRecord
                {
                    Values =
                        jObject["NameValue"].ToDictionary(row => (string) row["Name"], row => (string) row["Value"])
                };

答案 1 :(得分:1)

使用JSON.NET,Paste Special,“As JSON CLass”,它为您提供: -

public class Rootobject
{
public Namevalue[] NameValue { get; set; }
}

public class Namevalue
{
public string Name { get; set; }
public string Value { get; set; }
}

答案 2 :(得分:1)

我能够使用自定义转换器。如果使用JSON.NET标准可以做到这一点,我会很感激输入。

这是我的接收对象:

internal class ResponseRecord
{
    public string RowIndex { get; set; }

    [JsonProperty(PropertyName = "NameValue"), JsonConverter(typeof(JsonNameValueListToDictionaryConverter))]
    public Dictionary<string, string> Values { get; set; }
}

这是转换器代码:

/// <summary>
/// Converts the NameValue-array with object containing name and value to a Dictionary.
/// </summary>
internal class JsonNameValueListToDictionaryConverter : JsonConverter
{
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotSupportedException();
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        Dictionary<string, string> dictionary = existingValue as Dictionary<string, string> ?? new Dictionary<string, string>();

        if (reader.TokenType == JsonToken.StartArray)
        {
            int startDepth = reader.Depth;
            while (reader.Read())
            {
                if ((reader.Depth == startDepth) && (reader.TokenType == JsonToken.EndArray)) break;

                if (reader.TokenType == JsonToken.StartObject)
                {
                    KeyValuePair<string, string> kvp = GetKeyValueFromJsonObject(reader, "Name", "Value");
                    dictionary[kvp.Key] = kvp.Value; // always override existing keys
                }
                else
                {
                    throw new NotSupportedException(String.Format("Unexpected JSON token '{0}' while reading special Dictionary", reader.TokenType));
                }
            }
        }

        return dictionary;
    }

    private KeyValuePair<string, string> GetKeyValueFromJsonObject(JsonReader reader, string propNameKey, string propNameValue)
    {
        string key = null;
        string value = null;
        int startDepth = reader.Depth;
        while (reader.Read())
        {
            if ((reader.TokenType == JsonToken.EndObject) && (reader.Depth == startDepth)) break;

            if (reader.TokenType == JsonToken.PropertyName)
            {
                string propName = reader.Value as string;
                if (propName == null) continue;
                if (propName.Equals(propNameKey, StringComparison.InvariantCulture))
                {
                    key = reader.ReadAsString();
                }
                else if (propName.Equals(propNameValue, StringComparison.InvariantCulture))
                {
                    value = reader.ReadAsString();
                }
            }
        }
        return new KeyValuePair<string, string>(key, value);
    }

    public override bool CanConvert(Type objectType)
    {
        return (objectType.Equals(typeof(Dictionary<string, string>)));
    }

}