【问题标题】:Using Json.NET to convert a JObject to Dictionary<string, string> [duplicate]使用 Json.NET 将 JObject 转换为 Dictionary<string, string> [重复]
【发布时间】:2019-04-19 06:32:38
【问题描述】:

像这样使用 JSON 进行测试:

{\"key1\":\"value1\",\"key2\":\"value3\",\"key3\":[\"value4\"],\"key5\":\"value5\"}\n;

无效参数异常: 'Newtonsoft.Json.JsonConvert.DeserializeObject>(字符串)'

这是我的代码:

string json = "{\"action\":\"recognition\",\"command\":\"event\",\"eventid\":[\"1108\"],\"from_ip\":\"192.168.0.49\",\"user\":\"safetymaster\"}\n";
json = json.Replace("\n", "");  

var DeserializedJson= JsonConvert.DeserializeObject<dynamic>(json);                                
Dictionary<string, string> jsonDic = JsonConvert.DeserializeObject<Dictionary<string, string>>(DeserializedJson);

【问题讨论】:

  • key3/eventid 没有字符串值,而是字符串数组。我看不出您通过两次调用 DeserializeObject 来达到什么目的。因此,它应该只是var jsonDic = JsonConvert.DeserializeObject&lt;Dictionary&lt;string, object&gt;&gt;(json);。此外,无需替换新行。
  • @ckuri,如果您使用object,那么您可能需要将其转换为用户类型并且它会增加复杂性,您可以使用JToken 代替。
  • @er-sho 你是对的。我假设 eventid 列表将被反序列化为对象列表而不是 JArray,这使得访问列表条目很尴尬(即与访问只需转换为字符串的简单属性不同)。当然,最好的解决方案是他将其反序列化为具有正确指定属性和类型的适当类,以便更好地方便和类型安全。
  • @ckuri,如果你不确定json属性的类型,那么你可以使用JToken
  • 当 Json 以一种令人费解的方式变化和进化时,JToken 是一个强大的工具。我们只针对我们需要的属性。 F.e “所有子属性名称为 Foo,无论它们在 FooBar 节点下的什么位置。”很简单。 Json 由具有变形属性的非强类型语言提供服务(Php 数组,我在看你)经常需要使用自定义转换器或 JToken。但是当Json是知道的。上课有很大的好处。他们都可以实现相同的目标。

标签: c# json.net


【解决方案1】:

试试这个。

class Program
{
    static void Main(string[] args)
    {
        try {
            string json = "{\"action\":\"recognition\",\"command\":\"event\",\"eventid\":[\"1108\"],\"from_ip\":\"192.168.0.49\",\"user\":\"safetymaster\"}\n";
            json = json.Replace("\n", "");
            RootObject m = JsonConvert.DeserializeObject<RootObject>(json);
            string ipAddress = m.from_ip;
            string eventID = m.eventid[0];

        }
        catch (Exception ex)
        {
            Console.WriteLine(ex);
        }

    }
}

根据JSON对象定义一个类。

public class RootObject
{
    public string action { get; set; }
    public string command { get; set; }
    public List<string> eventid { get; set; }
    public string from_ip { get; set; }
    public string user { get; set; }
}

【讨论】:

    【解决方案2】:

    这可以通过两步过程完成:

    1. Dserialise 作为字典
    2. 使用 System.Linq 功能 (ToDictionary) 将上一个结果转换为 Dictionary

    例如:

    string json = "{\"action\":\"recognition\",\"command\":\"event\",\"eventid\":[\"1108\"],\"from_ip\":\"192.168.0.49\",\"user\":\"safetymaster\"}\n"; json = json.Replace("\n", "");
    
    Dictionary<string, object> jsonDic = JsonConvert.DeserializeObject<Dictionary<string, object>>(json);
    
    var jsonDic2 = jsonDic.ToDictionary(
        x => x.Key, 
        x => x.Value.ToString()
    );
    

    jsonDic2 中的上述结果是一个字典,内容如下:

    请注意:“eventid”字典条目的字符串值被格式化为 JSON 数组,因此您可能需要在必要时将其值转换为字符串数组:

    var eventIdList = jsonDic2.ContainsKey("eventid")
        ? Newtonsoft.Json.JsonConvert.DeserializeObject<string[]>(jsonDic2["eventid"])
        : new string[]{};
    

    【讨论】:

    • 谢谢!这个解决方案非常有用。
    【解决方案3】:

    您可以简单地获得价值:

     string json = "{\"action\":\"recognition\",\"command\":\"event\",\"eventid\":[\"1108\"],\"from_ip\":\"192.168.0.49\",\"user\":\"safetymaster\"}\n";            
     var jsonData = JsonConvert.DeserializeObject<JObject>(json);
     var action = jsonData["action"].ToString();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-30
      • 1970-01-01
      • 1970-01-01
      • 2010-10-17
      • 2014-10-22
      相关资源
      最近更新 更多