Sergey Shuvalov
Sergey Shuvalov

Reputation: 2128

return json from JsonConvert.SerializeXNode with proper type

var test = new
            {
                TestStr = "test",
                TestNumber = 123,
                TestDate = new DateTime(1986, 1, 13, 17, 50, 31),
                TestBool = true
            };

var xml = JsonConvert.DeserializeXNode(JsonConvert.SerializeObject(test), "test");

This code return nice xml element:

<test>
  <TestDate>1986-01-13T14:50:31Z</TestDate>
  <TestBool>true</TestBool>
  <TestNumber>123</TestNumber>
  <TestStr>test</TestStr>
</test>

When I try convert this xml back to JSON:

var json = JsonConvert.SerializeXNode(xml, Formatting.None, true);

I get JSON only with String properties.

What should I do to get json with proper types?

Upvotes: 0

Views: 3226

Answers (1)

Brian Rogers
Brian Rogers

Reputation: 129777

JSON and XML are different serialization formats, and have different capabilities. JSON can differentiate between string, number, and boolean whereas XML treats everything as a string. Therefore, when you convert from JSON to XML and back, the type information gets lost. One way to handle this is to use an strongly-typed intermediate model when converting back and forth. In other words, instead of converting directly from XML to JSON, deserialize your XML to the model, then serialize the model to JSON. The model will force the data to be the correct types.

Here's an example:

class Program
{
    static void Main(string[] args)
    {
        string xml = @"
        <test>
          <TestDate>1986-01-13T14:50:31Z</TestDate>
          <TestBool>true</TestBool>
          <TestNumber>123</TestNumber>
          <TestStr>test</TestStr>
        </test>";

        XmlSerializer ser = new XmlSerializer(typeof(Test));
        Test test = (Test)ser.Deserialize(new StringReader(xml));
        string json = JsonConvert.SerializeObject(test, Formatting.Indented);
        Console.WriteLine(json);
    }
}

[XmlType("test")]
public class Test
{
    public string TestStr { get; set; }
    public int TestNumber { get; set; }
    public DateTime TestDate { get; set; }
    public bool TestBool { get; set; }
}

Output:

{
  "TestStr": "test",
  "TestNumber": 123,
  "TestDate": "1986-01-13T14:50:31Z",
  "TestBool": true
}

Upvotes: 3

Related Questions