Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.5k views
in Technique[技术] by (71.8m points)

c# - Applying JsonDictionary attribute to dictionary

If I try to add the JsonDictionary attribute to a .net Dictionary(Of Integer, MyClass), the compiler tells me, that the attribute could not be applied. Why is this?

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

I basically couldn't find any examples of how to use the JsonDictionary online.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

<JsonDictionary()> can be applied to a type (a class or interface) to force Json.NET's default contract resolver (and its subclasses) to generate a dictionary contract for the type. It is part of a family of three similar attributes:

  • <JsonObject()>. Force a type to be serialized as a JSON object. Useful to force serialization of collection properties instead of items as shown here.
  • <JsonArray()>. Force a type to serialized as a JSON array. Possibly useful to, e.g., force a dictionary to be serialized as a key/value pair array.
  • <JsonDictionary()>. Force a type to be interpreted as a dictionary and serialized as a JSON object. (It must still implement IDictionary or IDictionary<TKey, TValue> for this to work, of course.)

On the face of it <JsonDictionary()> does not seem that useful because DefaultContractResolver.CreateContract(Type objectType) checks that the incoming type implements IDictionary before checking for any other interface implementations. However, the attribute has several properties that could be useful in customizing how a dictionary is serialized, including:

  • NamingStrategyType and NamingStrategyParameters allow control of casing and name-mapping of dictionary keys.

    For instance, the following dictionary will always serialize its keys literally, without renaming, even if CamelCasePropertyNamesContractResolver is in use:

    <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
    
  • ItemConverterType, ItemConverterParameters, ItemIsReference, ItemReferenceLoopHandlingand ItemTypeNameHandling allow customization of how dictionary values are serialized.

    For instance, in the following dictionary type, the values are always stored with reference preservation enabled:

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

    Or, for a dictionary type containing enum values, you might apply StringEnumConverter as an ItemConverterType to force the values to be serialized as strings.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...