【问题标题】:How to de-serialize a json object containing variable number of objects and get them as a key value collection in C#?如何反序列化包含可变数量对象的json对象并将它们作为C#中的键值集合?
【发布时间】:2015-11-18 06:31:42
【问题描述】:

如何反序列化以下 JSON 对象并获取 Dictionary 集合,其中键(字符串)应该是方法名称,对象是 C# 中的详细信息。

{
"methods": {
    "password.2": {
      "title": "Password CustomerID",
      "type": "password"
    },
    "ubikey.sms.1": {
      "title": "SMS",
      "type": "stepup",
      "password": "password.2",
      "stepUp": "sms"
    },
    "tupas.test.1": {
      "title": "TUPAS Emulator",
      "type": "proxy"
    }
  }
}

如果它是一个方法数组,我可以很容易地使用数组对其进行序列化。但由于它本身就是一个键值对,所以我被卡住了。

我正在向特定 api 发出 WebRequest 并将结果作为 json 获取。

用于序列化对象的代码来自https://msdn.microsoft.com/en-us/library/hh674188.aspx

【问题讨论】:

  • 你想要这本词典的目的是什么?您可以轻松解析 json 并在 c# 中获取类型化的对象
  • 方法名称是指“password.2”、“ubikey.sms.1”、“tupas.test.1”?
  • 同样作为一个对象,在解析上面的 json 时,它会产生一个对象,其中包含一个 each 方法作为一个单独的属性。方法的数量可以变化。我需要一个包含方法名称及其详细信息的对象列表。
  • 您使用的是什么版本的 .net 框架?
  • @Alireza .NET Framework 4.5

标签: c# json serialization


【解决方案1】:

linked to的页面描述了如何使用DataContractJsonSerializer反序列化JSON。您可以使用该序列化程序将您的"methods" 对象反序列化为Dictionary如果您使用的是.Net 4.5 或更高版本,还可以设置DataContractJsonSerializerSettings.UseSimpleDictionaryFormat = true。完成此操作后,您可以定义以下类:

public class Method
{
    public string title { get; set; }
    public string type { get; set; }
    public string password { get; set; }
    public string stepUp { get; set; }
}

public class Response
{
    public Dictionary<string, Method> methods { get; set; }
}

并将它们解析如下:

        var settings = new DataContractJsonSerializerSettings { UseSimpleDictionaryFormat = true };
        var jsonSerializer = new DataContractJsonSerializer(typeof(Response), settings);
        var jsonResponse = jsonSerializer.ReadObject(response.GetResponseStream()) as Response;

如果您使用的是早期版本的 .Net,您可能需要使用不同的序列化程序,例如 Json.NET,因为在早期版本中,DataContractJsonSerializer 将字典序列化为 key/value pair arrays

【讨论】:

  • 谢谢,工作.. 决定使用这种方法,因为我可以避免 JSON.net 依赖..
【解决方案2】:

JSON.net 这样做:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Newtonsoft.Json;

namespace ConsoleApplication1
{
    class Program
    {

        static void Main(string[] args)
        {
            string json = @"{
""methods"": {
    ""password.2"": {
      ""title"": ""Password CustomerID"",
      ""type"": ""password""
    },
    ""ubikey.sms.1"": {
      ""title"": ""SMS"",
      ""type"": ""stepup"",
      ""password"": ""password.2"",
      ""stepUp"": ""sms""
    },
    ""tupas.test.1"": {
      ""title"": ""TUPAS Emulator"",
      ""type"": ""proxy""
    }
  }
}";

            Dictionary<string, Dictionary<String,Dictionary<String,String>>> values = JsonConvert.DeserializeObject<Dictionary<string, Dictionary<String,Dictionary<String,String>>>>(json);
        }


    }
}

【讨论】:

    【解决方案3】:
     dynamic results = JsonConvert.DeserializeObject(JsonString());
     Dictionary<string, object> dictionary = new Dictionary<string, object>();
     foreach (var o in results.methods)
     {
         dictionary[o.Name] = o.Value;
     }
    
    private static string JsonString()
    {
             return "{\"methods\": {\"password.2\": {\"title\": \"Password CustomerID\",\"type\": \"password\"},\"ubikey.sms.1\": {\"title\": \"SMS\",\"type\": \"stepup\",\"password\": \"password.2\",\"stepUp\": \"sms\"},\"tupas.test.1\": {\"title\": \"TUPAS Emulator\",\"type\": \"proxy\"}}}";
    }
    

    【讨论】:

      猜你喜欢
      • 2015-11-14
      • 1970-01-01
      • 1970-01-01
      • 2015-06-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多