【问题标题】:Json.NET deserializing a selectlist / multiselectlistJson.NET 反序列化选择列表/多选列表
【发布时间】:2018-11-19 12:16:09
【问题描述】:

我在 ASP.NET 中使用 Json.NET 序列化了 MultiSelectList(启用了 TypeNameHandling),结果如下:

"MyMultiSelectList": {
    "$type": "System.Web.Mvc.MultiSelectList, System.Web.Mvc",
    "$values": [
      {
        "Disabled": false,
        "Selected": true,
        "Text": "Text1",
        "Value": "Value1"
      },
      {
        "Disabled": false,
        "Selected": false,
        "Text": "Text2",
        "Value": "Value2"
      },
      {
        "Disabled": false,
        "Selected": false,
        "Text": "Text3",
        "Value": "Value3"
      }
    ]
  }

当使用this method 将此 Json 反序列化回 MultiSelectList 而没有任何自定义转换器时,我得到一个带有 3 个 SelectListItems 的 MultiSelectList,其中它们的 Text 属性设置为“System.Web.Mvc.SelectListItem”并且它们的 Value 属性为空。

首先,我假设 Json.NET 无法正确反序列化 SelectListItems,所以我为 SelectListItem 类型创建了一个Custom JsonConverter。我的转换器正确创建了 SelectListItems,但结果仍然相同。

然后我尝试为 MultiSelectList 类型制作一个自定义转换器,但 Json.NET 从未调用该代码。

也许这个问题与 MultiSelectList 没有默认的空构造函数有关,但我没有办法尝试。

【问题讨论】:

    标签: asp.net json json.net selectlist selectlistitem


    【解决方案1】:

    使用 QuickType 创建自定义类:

    public class CustomSelectList
        {
            [JsonProperty("MyMultiSelectList")]
            public MyMultiSelectList MyMultiSelectList { get; set; }
        }
    
        public class MyMultiSelectList
        {
            [JsonProperty("$type")]
            public string Type { get; set; }
    
            [JsonProperty("$values")]
            public Value[] Values { get; set; }
        }
    
        public class Value
        {
            [JsonProperty("Disabled")]
            public bool Disabled { get; set; }
    
            [JsonProperty("Selected")]
            public bool Selected { get; set; }
    
            [JsonProperty("Text")]
            public string Text { get; set; }
    
            [JsonProperty("Value")]
            public string ValueValue { get; set; }
        }
    

    反序列化

    var customList = JsonConvert.DeserializeObject<CustomSelectList>(json);
    

    然后将其加载到列表中

    foreach (var item in customList.MyMultiSelectList.Values)
        multiSelectList.Add(new SelectListItem{ Value= item.ValueValue, Text=item.Text });
    

    并填充 MultiSelectList(尚未测试)

    var multiList = new MultiSelectList(list);
    

    另一种做法是,先加载到支持序列化的数据结构中(如List&lt;KeyValuePair&lt;string,string&gt;&gt;:

    var serializableList = new List<KeyValuePair<string, string>>();
    foreach(var item in selectList)
        serializableList.Add(new KeyValuePair<string, string>(item.Text, item.Value));
    

    然后序列化serializableList,就会得到

    [{"Key":"select item value","Value":"select item text"}]
    

    如果你想存储更多信息,例如项目是否被选中,你可以做List&lt;Tuple&lt;string,string,bool&gt;&gt;

    当您需要重建您的MultiSelectList 时,只需对其进行反序列化,将其添加到List&lt;SelectListItem&gt;,然后传递列表以构造MultiSelectList (new MultiSelectLust(list))

    【讨论】:

    • 听起来是个好主意,但是我不能直接调用sonConvert.DeserializeObject&lt;CustomSelectList&gt;(json),因为我的 MultiSelectList 包含在其他 3 层深的对象中。
    • 在这种情况下,您可以执行dynamic list = JObject.Parse(json); 并从根级别访问它
    • 我认为这也是有问题的。我不知道那里是否有 MultiSelectList。有时有,但有时没有。
    • 你想通过序列化多选列表来实现什么?您可以将值存储在可序列化/可反序列化的 List 中,然后用它做任何你想做的事情
    • 我发现了我的问题到底是什么:由于我正在反序列化为 Dictionairy (并且 SelectList 是对象之一),Json.NET 不会触发自定义转换器SelectList(因为类型将是对象而不是 SelectList)。但是,拥有一个用于 Dictionairy 的自定义转换器允许我通过执行默认的 Json.NET 字典序列化并在遇到 (Multi)SelectList 时进行干扰来使用您为序列化和反序列化提供的类。
    猜你喜欢
    • 2015-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-01
    • 2012-04-09
    • 1970-01-01
    相关资源
    最近更新 更多