将JsonDictionary属性应用于字典

时间:2017-03-30 15:45:21

标签: c# .net vb.net json.net

如果我尝试将JsonDictionary属性添加到.net Dictionary(Of Integer,MyClass),编译器告诉我,该属性无法应用。这是为什么?

<JsonDictionary()>
Public ReadOnly Property monatswerte As Dictionary(Of Integer, MyClass)

我基本上找不到任何关于如何在线使用JsonDictionary的例子。

2 个答案:

答案 0 :(得分:3)

<JsonDictionary()>可以应用于类型(类或接口)以强制Json.NET的default contract resolver(及其子类)为类型生成dictionary contract 。它是三个相似属性的一部分:

  • <JsonObject()>。强制将类型序列化为JSON对象。用于强制集合属性的序列化而不是显示here的项目。
  • <JsonArray()>。强制将类型序列化为JSON数组。例如,强制将字典强制序列化为键/值对数组可能是有用的。
  • <JsonDictionary()>。强制将类型解释为字典并序列化为JSON对象。 (当然,它必须实现IDictionaryIDictionary<TKey, TValue>才能发挥作用。)

在它的表面<JsonDictionary()>似乎没有用,因为DefaultContractResolver.CreateContract(Type objectType)在检查任何其他接口实现之前检查传入类型是否实现IDictionary。但是,该属性有几个properties,可用于自定义字典的序列化方式,包括:

  • NamingStrategyTypeNamingStrategyParameters允许控制字典的大小写和名称映射。

    例如,即使正在使用CamelCasePropertyNamesContractResolver,以下字典也会始终按字面顺序序列化,而无需重命名:

    <JsonDictionary(NamingStrategyType := GetType(LiteralKeyDictionaryNamingStrategy))> _
    Public Class LiteralKeyDictionary(Of TValue)
        Inherits Dictionary(Of String, TValue)
    End Class
    
    Public Class LiteralKeyDictionaryNamingStrategy
        Inherits DefaultNamingStrategy
    
        Public Sub New()
            ProcessDictionaryKeys = False
        End Sub
    End Class
    
  • ItemConverterTypeItemConverterParametersItemIsReferenceItemReferenceLoopHandlingItemTypeNameHandling允许自定义词典的序列化方式。

    例如,在以下字典类型中,值始终存储为启用reference preservation

    <JsonDictionary(ItemIsReference := true)> _
    Public Class ReferenceObjectDictionary(of TKey, TValue As {Class, New})
        Inherits Dictionary(Of TKey, TValue)
    End Class
    

    或者,对于包含enum值的字典类型,您可以将StringEnumConverter应用为ItemConverterType以强制将值序列化为字符串。

答案 1 :(得分:0)

@ dbc的答案很棒,+ 1&#39; d(而且这种方法比明确的TypeConverter路线要麻烦得多)。这是一个F#riff / rip-off / port:

[<JsonDictionary(NamingStrategyType =
                    typedefof<VerbatimKeyDictionaryNamingStrategy>)>]
type VerbatimKeyDictionary<'value>(values : IDictionary<string,'value>) =
    inherit Dictionary<string,'value>(values)
    override this.Equals other =
        let that = other :?> IDictionary<string,'value>
        that <> null
        && this.Count = that.Count
        && Seq.isEmpty (this |> Seq.except that)
    override __.GetHashCode () = 0
and VerbatimKeyDictionaryNamingStrategy() =
    inherit Newtonsoft.Json.Serialization.DefaultNamingStrategy(
         ProcessDictionaryKeys = false)