将JSON反序列化为C# - 尝试将JSON关联数组转换为Dictionary<string, string>

3

我有这个JSON:

{
    "AutoRefreshEnabled" : false,
    "AutoRefreshInterval" : 1,
    "AutoCycleEnabled" : false,
    "AutoCycleInterval" : 1,
    "Tabs" : {
        "RadTab_Home",
        "Dashboard"
    },
    "CommandName" : "Update Global Settings"
}

我试图将它存储在这个类中,但我不确定如何处理嵌套的Tabs对象。可能有任意数量的选项卡大于0(所以是1+,第一个键始终为RadTab_Home)。选项卡不应该是string[]。我想要它是一个Dictionary<string, string>,但我不确定如何表达。

[DataContract]
public class GlobalSettingsJSON
{
    private static readonly ILog Logger = 
        LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);

    public GlobalSettingsJSON() { }

    public GlobalSettingsJSON(string commandName, string autoRefreshEnabled, 
        string autoRefreshInterval, string autoCycleEnabled, 
        string autoCycleInterval, Dictionary<string, string> tabs)
    {
        Logger.InfoFormat("Command Name: {0}, DockID: {1}, " +
            "AutoRefreshEnabled: {2}, AutoRefreshInterval: {3}, " +
            "AutoCycleEnabled: {4}, AutoCycleInterval: {5}",
            commandName, autoRefreshEnabled, autoRefreshInterval, 
            autoCycleEnabled, autoCycleInterval);

        CommandName = commandName;
        AutoRefreshEnabled = autoRefreshEnabled;
        AutoRefreshInterval = autoRefreshInterval;
        AutoCycleEnabled = autoCycleEnabled;
        AutoCycleInterval = autoCycleInterval;
        Tabs = tabs;
    }

    [DataMember(Name = "CommandName")]
    public string CommandName { get; set; }

    [DataMember(Name = "AutoRefreshEnabled")]
    public string AutoRefreshEnabled { get; set; }

    [DataMember(Name = "AutoRefreshInterval")]
    public string AutoRefreshInterval { get; set; }

    [DataMember(Name = "AutoCycleEnabled")]
    public string AutoCycleEnabled { get; set; }

    [DataMember(Name = "AutoCycleInterval")]
    public string AutoCycleInterval { get; set; }

    [DataMember(Name = "Tabs")]
    public Dictionary<string, string> Tabs { get; set; }
}

编辑:现在Tabs不返回任何数据,但不会抛出错误。 编辑:DataContractJsonSerializer不支持反序列化到字典。然而,JSON.net可以! 编辑:使用Newtonsoft的JSON反序列化器代码完美运行。


http://blogs.msdn.com/b/rakkimk/archive/2009/01/30/asp-net-json-serialization-and-deserialization.aspx 在底部有一个使用字符串数组的示例。这很接近..我想知道是否可以适应它。 - Sean Anderson
1个回答

4
如果您希望Tabs属性是一个Dictionary<string, string>,那么您在JSON中的表示不正确。目前,您的表示如下:
"Tabs" : [
    "RadTab_Home",
    "Dashboard"
],

这应该是一个string[]。如果你想要一个映射(即Dictionary<string, string>),那么你需要一个与值相关联的,因此,在 JSON 中需要不同的表示:

"Tabs" : [
    { "key1" : "RadTab_Home" },
    { "key2" : "Dashboard" }
],

使用这个方法,您可以创建一个Dictionary<string, string>,因为您有一个与值相关联的键。键是要创建一个类,像这样:
// NOTE: You can use POCO DataContract serialization for this type.
[DataContract]
public class Pair
{
    [DataMember]
    public string Key { get; set; }

    [DataMember]
    public string Value { get; set; }
}

然后像这样定义您的属性:
[DataMember]
public Pair[] Tabs { get; set; }

您可以使用LINQ轻松将其转换为Dictionary<string, string>
// Deserialized instance.
MyClass instance = ...;

// Map
IDictionary<string, string> tabsMap = instance.Tabs.
    ToDictionary(p => p.Key, p => p.Value);

你可以将它添加为类的一个方法,但这是你要做出的设计决策(我没有将其添加到类中,因为我假设这是一个数据传输对象)。

我正在使用jQuery的$.toJSON()方法来序列化一个关联数组。我使用关联数组进行键/值查找。在JSON序列化后,我需要进行修改吗? - Sean Anderson
1
@Sean Anderson:关联数组长什么样?你在Tabs属性的值中所拥有的并不是关联数组,而只是一个普通的数组。 - casperOne
@casperOne -- 我已经进行了更改,现在我的字典中没有任何数据,但也没有错误。“{”AutoRefreshEnabled“:false,”AutoRefreshInterval“:1,”AutoCycleEnabled“:false,”AutoCycleInterval“:1,”Tabs“:{”RadTab_Home“:”Dashboard“},”CommandName“:”Update Global Settings“}”这是我的JSON现在的样子。选项卡的方括号变成了花括号,但我没有看到方括号包裹花括号。我应该吗? - Sean Anderson
@Sean Anderson:为了让你的生活更轻松,我会创建一个中间类型,该类型具有键和值(均为字符串),然后将其序列化为这些类类型的数组。然后,你可以轻松地将该数组映射到字典中(一个属性是键,另一个是值)。 - casperOne
@Sean Anderson:我已经更新了我的答案以反映我的建议。 - casperOne
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接