Search code examples
c#jsonserializationdatacontractdatacontractjsonserializer

DataContractJsonSerializer not working


I use the DataContractJsonSerializer to convert a JSON string into a class, but always return an empty object. I tested the string with the' JSON Viewer' extension in Notepad, is valid. Searched for a bug for a long time and compared other examples.

This is my JSON string in shortened form:

{
"error":[],
"result": {
        "BCH": {"aclass":"currency","altname":"BCH","decimals":10,"display_decimals":5},
        "DASH": {"aclass":"currency","altname":"test"}
    }
}

The classes GetAssetInfoResponse and AssetInfo contain properties with DataMember attributes, but the property Result (after Deserialize) does not contain any objects.

[DataContract]
[KnownType(typeof(AssetInfo))]
public class GetAssetInfoResponse 
{
    [DataMember(Name = "error")]
    public List<string> Error { get; set; }

    [DataMember(Name = "result")]
    public List<Dictionary<string, AssetInfo>> Result { get; set; }
}

[DataContract]
public class AssetInfo
{
    /// <summary>
    /// Alternate name.
    /// </summary>
    [DataMember(Name = "altname")]
    public string Altname { get; set; }

    /// <summary>
    /// Asset class.
    /// </summary>
    [DataMember(Name = "aclass")]
    public string Aclass { get; set; }

    /// <summary>
    /// Scaling decimal places for record keeping.
    /// </summary>
    [DataMember(Name = "decimals")]
    public int Decimals { get; set; }

    /// <summary>
    /// Scaling decimal places for output display.
    /// </summary>
    [DataMember(Name = "display_decimals")]
    public int DisplayDecimals { get; set; }
}

This is my test code:

        var stream = new MemoryStream(Encoding.Unicode.GetBytes(strName))
        {
            Position = 0
        };
        var serializer = new DataContractJsonSerializer(typeof(GetAssetInfoResponse));
        GetAssetInfoResponse test = (GetAssetInfoResponse)serializer.ReadObject(stream);

        Console.ReadLine();

I can't use the Newtonsoft.Json extension because the project should not contain any external dependencies. Is there another way to transfer JSON strings into classes?

Thank you for your time


Solution

  • You declare Result as a List<Dictionary<string, AssetInfo>> but from the format it looks like a dictionary, not a list of dictionaries (because it starts with {, this is used for objects, or dictionaries, not [ which is used for arrays/lists) . To use this format for dictionaries, you need to configure the UseSimpleDictionaryFormat property

    var serializer = new DataContractJsonSerializer(typeof(GetAssetInfoResponse), new DataContractJsonSerializerSettings
    {
        UseSimpleDictionaryFormat = true
    });
    

    With this setting and this change, it worked:

    public Dictionary<string, AssetInfo> Result { get; set; }