2

I am attempting to deserialize a json file into a List of Objects. The JSON file requires that I use UTF8. I am attempting to do it this way below.

FileStream reader1 = new FileStream(fileName, FileMode.Open, FileAccess.Read);
StreamReader streamReader1 = new StreamReader(reader1, Encoding.UTF8);
string jsonString1 = streamReader1.ReadToEnd();

byte[] byteArray1 = Encoding.UTF8.GetBytes(jsonString1);
MemoryStream stream1 = new MemoryStream(byteArray1);

DataContractJsonSerializer inputSerializer2;
inputSerializer2 = new DataContractJsonSerializer(typeof(List<Country>));
c = (List<Country>)inputSerializer2.ReadObject(stream1);
stream1.Close();

This actually reads the file into the list but only saves nulls and 0s. Is this correct? All the references are in the right place from the looks of it. Is it just my toString() on my classes that are messed up?

Thank you.

edit: Below is my class and its member variables that I am trying to deserialize into along with a snippet of the JSON and my toString override.

[DataContract]
public class Country
{
    #region Member Variables

    private string m_name;
    private string m_capital;
    private string m_region;
    private string m_subRegion;
    private int m_population;
    private List<Currency> m_currency = new List<Currency>();
    private List<Language> m_language = new List<Language>();

//Rest of class here

public override string ToString()
    {
        return "The country name is " + Name + "\n" + "The country capital is " + Capital + "\n" + "The country region is " + Region
            + "\n" + "The country sub region is " + SubRegion + "\n" + "The country population is " + Population + "\n"
            + "The country currency is " + Currencies + "\n" + "The country language is " + Languages;
    }

/--------------------------------------------------------------/

[
{
  "currencies": [
    {
      "code": "AFN",
      "name": "Afghan afghani",
      "symbol": "؋"
    }
  ],
  "languages": [
    {
      "iso639_1": "ps",
      "iso639_2": "pus",
      "name": "Pashto",
      "nativeName": "پښتو"
    },
    {
      "iso639_1": "uz",
      "iso639_2": "uzb",
      "name": "Uzbek",
      "nativeName": "Oʻzbek"
    },
    {
      "iso639_1": "tk",
      "iso639_2": "tuk",
      "name": "Turkmen",
      "nativeName": "Türkmen"
    }
  ],
  "name": "Afghanistan",
  "capital": "Kabul",
  "region": "Asia",
  "subregion": "Southern Asia",
  "population": 27657145
}

]

visuslov
  • 23
  • 4
  • The JSON file has special characters that require it to be read via UTF8. – visuslov Nov 01 '18 at 04:10
  • 1
    I would personally recommend getting the Newtonsoft json Nuget package, as that one is much more widely used, and makes serialization and de-serialization easier https://www.newtonsoft.com/json – SomeStudent Nov 01 '18 at 04:12
  • @SomeStudent I wish I could but my professor wants everything done this way. – visuslov Nov 01 '18 at 04:13
  • Thank you for your suggestion. I have gone along and went with your suggestion but still received an error. Cannot convert from system.io.streamReader to system.io.stream. It does not even let me compile it. – visuslov Nov 01 '18 at 04:19
  • Will check, sec. – ProgrammingLlama Nov 01 '18 at 04:21
  • Based on your additional comments, etc. I'm at a bit of a loss to what the issue you're experiencing is. Hopefully someone else has more experience with the serializer than I do. It has been quite some time since I used it - I was fortunate to be able to switch to JSON.NET :) – ProgrammingLlama Nov 01 '18 at 04:37
  • 1
    @John. Thanks for going out of your way to help me man. I wish I could do the same :( – visuslov Nov 01 '18 at 04:38
  • No worries. Sorry I couldn't resolve your issue. As a suggestion for getting more help: try adding a sample JSON file (minimal to reproduce the issue), and also all of the relevant class definitions which you're deserializing to. – ProgrammingLlama Nov 01 '18 at 04:53

1 Answers1

0

All variables name need to match the json, public, and have getter/setter.

    [DataContract]
    public class Country
    {
        [DataMember]  
        public string name { get; set; }
        [DataMember]  
        public string capital { get; set; }
        [DataMember]  
        public string region { get; set; }
        [DataMember]  
        public string subRegion { get; set; }
        [DataMember]  
        public int population { get; set; }
        [DataMember]  
        public Currency[] currencies { get; set; }
        [DataMember]  
        public Language[] languages { get; set; }

        public override string ToString()
        {
            return "The country name is " + name + "\n" + "The country capital is " + capital + "\n" + "The country region is " + region
                   + "\n" + "The country sub region is " + subRegion + "\n" + "The country population is " + population + "\n"
                   + "The country currency is " + currencies + "\n" + "The country language is " + languages;
        }
    }

    [DataContract]  
    public class Currency
    {
        [DataMember]  
        public string code { get; set; }
        [DataMember]  
        public string name { get; set; }
        [DataMember]  
        public string symbol { get; set; }
    }

    [DataContract]
    public class Language
    {
        [DataMember]  
        public string iso639_1 { get; set; }
        [DataMember]  
        public string iso639_2 { get; set; }
        [DataMember]  
        public string name { get; set; }
        [DataMember] 
        public string nativeName { get; set; }
    }

It will work now, except in ToString(), the currencies and languages will be printed as Currency[] and Languages[]. You need to create another function to print the Currency members.

Also, it's preferable to use using for the MemoryStream to ensure the stream will be automatically disposed.

using (var ms = new MemoryStream(Encoding.UTF8.GetBytes(jsonString1)))  
{  
    // Deserialization from JSON  
    DataContractJsonSerializer deserializer = new DataContractJsonSerializer(typeof(List<Country>));  
    var countries = (List<Country>)deserializer.ReadObject(ms);  
}  
currarpickt
  • 2,290
  • 4
  • 24
  • 39