Deserialize JSON from a file [duplicate] - c#

I have some JSON:
{
"foo" : [
{ "bar" : "baz" },
{ "bar" : "qux" }
]
}
And I want to deserialize this into a collection. I have defined this class:
public class Foo
{
public string bar { get; set; }
}
However, the following code does not work:
JsonConvert.DeserializeObject<List<Foo>>(jsonString);
How can I deserialize my JSON?

That JSON is not a Foo JSON array. The code JsonConvert.DeserializeObject<T>(jsonString) will parse the JSON string from the root on up, and your type T must match that JSON structure exactly. The parser is not going to guess which JSON member is supposed to represent the List<Foo> you're looking for.
You need a root object, that represents the JSON from the root element.
You can easily let the classes to do that be generated from a sample JSON. To do this, copy your JSON and click Edit -> Paste Special -> Paste JSON As Classes in Visual Studio.
Alternatively, you could do the same on http://json2csharp.com, which generates more or less the same classes.
You'll see that the collection actually is one element deeper than expected:
public class Foo
{
public string bar { get; set; }
}
public class RootObject
{
public List<Foo> foo { get; set; }
}
Now you can deserialize the JSON from the root (and be sure to rename RootObject to something useful):
var rootObject = JsonConvert.DeserializeObject<RootObject>(jsonString);
And access the collection:
foreach (var foo in rootObject.foo)
{
// foo is a `Foo`
}
You can always rename properties to follow your casing convention and apply a JsonProperty attribute to them:
public class Foo
{
[JsonProperty("bar")]
public string Bar { get; set; }
}
Also make sure that the JSON contains enough sample data. The class parser will have to guess the appropriate C# type based on the contents found in the JSON.

Related

Serialize C# class into nested JSON with specified paths in JsonProperty attribute

I have flat C# class with lots of properties and I want to serialize an instance of that class into JSON using Json.NET. While serializing, I need to produce a JSON string that is nested. I know that I can create subclasses to achieve this but this is unnecessary overhead.
Let's assume I have this class:
public class MyClass{
[JsonProperty("subgroupa.myotherproperty")]
public int MyProperty {get;set;} = 5;
}
How can I get this JSON:
{
"subgroupa": {
"myotherproperty": 5
}
}
In the past, I was able to deserialize such a nested JSON string into a flat object. Therefore, I believe Json.NET can also do the opposite.
using System.Text.Json;
public class MyClass{
[JsonProperty("subgroupa.myotherproperty")]
public int MyProperty {get;set;} = 5;}
string subgroupa = JsonSerializer.Serialize(MyClass);

why doesnt my json string convert into c# objects? [duplicate]

I have some JSON:
{
"foo" : [
{ "bar" : "baz" },
{ "bar" : "qux" }
]
}
And I want to deserialize this into a collection. I have defined this class:
public class Foo
{
public string bar { get; set; }
}
However, the following code does not work:
JsonConvert.DeserializeObject<List<Foo>>(jsonString);
How can I deserialize my JSON?
That JSON is not a Foo JSON array. The code JsonConvert.DeserializeObject<T>(jsonString) will parse the JSON string from the root on up, and your type T must match that JSON structure exactly. The parser is not going to guess which JSON member is supposed to represent the List<Foo> you're looking for.
You need a root object, that represents the JSON from the root element.
You can easily let the classes to do that be generated from a sample JSON. To do this, copy your JSON and click Edit -> Paste Special -> Paste JSON As Classes in Visual Studio.
Alternatively, you could do the same on http://json2csharp.com, which generates more or less the same classes.
You'll see that the collection actually is one element deeper than expected:
public class Foo
{
public string bar { get; set; }
}
public class RootObject
{
public List<Foo> foo { get; set; }
}
Now you can deserialize the JSON from the root (and be sure to rename RootObject to something useful):
var rootObject = JsonConvert.DeserializeObject<RootObject>(jsonString);
And access the collection:
foreach (var foo in rootObject.foo)
{
// foo is a `Foo`
}
You can always rename properties to follow your casing convention and apply a JsonProperty attribute to them:
public class Foo
{
[JsonProperty("bar")]
public string Bar { get; set; }
}
Also make sure that the JSON contains enough sample data. The class parser will have to guess the appropriate C# type based on the contents found in the JSON.

Deserialize multi-type JSON array using DataContracts

Currently, I have some JSON data that I am attempting to deserialize using the DataContractJsonSerializer class. However, one of the arrays in the data contains multiple types of objects. Is there a way to deserialize this data properly? I am aware that a very similar question exists, but I would prefer not to use Json.NET or any other third-party libraries.
EDIT: A small example:
In this instance, let's say the JSON is of form [{"foo":string},{"bar":string},{"foo":string},{"foo":string},...] where each element is either of form {"foo":string} or {"bar":string}. Then, the contracts could be set up as such:
[DataContract]
class Foo { [DataMember] public string foo; }
[DataContract]
class Bar { [DataMember] public string bar; }
In this context, my question is, how do I deserialize this array of Foos and Bars?
This does not sound right. There should not be two completely different types in a single array. Given the JSON provided I would try something like this....
[DataContract]
class SomeClass
{
[DataMember]
public string foo { get; set;}
[DataMember]
public string bar { get; set;}
}
Then check for IsNullOrWhiteSpace() on each property.
Updated with more code...
static void Main(string[] args)
{
SomeClass[] output;
var json = "[{\"foo\":\"value\"},{\"bar\":\"value\"},{\"foo\":\"value1\"},{\"foo\":\"value1\"}]";
using (var ms = new MemoryStream(Encoding.Unicode.GetBytes(json)))
{
var deserializer = new DataContractJsonSerializer(typeof(SomeClass[]));
output = (SomeClass[])deserializer.ReadObject(ms);
}
// do something with output
Console.WriteLine(output.Length);
}

Serializing XML with flat repeating structure

I need to serialize some XML to an object. I don't have control over the structure of the XML so I'm stuck with this situation. The structure is similar to this example:
<A>
<B>Elements that are the stuff of B</B>
<C>Stuff about the stuff in B</C>
<B>Different stuff</B>
<C>Stuff about the different stuff</C>
<C>Some more stuff about the different stuff</C>
<B>Weird stuff</B>
<C>Stuff about the Weird Stuff</C>
<C>Still more stuff about the Weird Stuff</C>
<D>New thing that goes with the Weird Stuff</D>
<B>Things</B>
<C>Stuff about Things</C>
</A>
I'd like to get this serialized to an object that maintains the information about the sibling structure.
public class A
{
public List<BCD> BCD {get; set;}
}
public class BCD
{
public B Bfield {get; set;}
public List<C> Cfield {get; set;}
public D Dfield {get; set;}
}
public class B
{
// class details
}
public class C
{
// class details
}
public class D
{
// class details
}
When I try this, it doesn't work. Is there anything I can do to maintain that structure using the XMLSerializer?
So I kept looking around for a solution and came up with this which is not exactly what I was looking for. This class structure retains the order of the sibling elements within the collection but does not create objects to represent a discrete group of the siblings.
public class A
{
[XmlElementAttribute("B", typeof(B))]
[XmlElementAttribute("C", typeof(C))]
[XmlElementAttribute("D", typeof(D))]
public List<object> BCD {get; set;}
}
public class B
{
// class details
}
public class C
{
// class details
}
public class D
{
// class details
}
The end result is BCD is a collection of the B,C,D objects in the order they appear in the XML.
You can try below steps:
convert your xml to xslt using xsd.exe(feature of VS)
convert xslt to class again by using xsd.exe
try to serialize and deserialize your xml to this class object.
now you can play with this class object to perform any action.
Hope this will help..

Object serialization and derived classes; controlling xml output

I have 2 derived classes that will be serialized into xml.
While the code works fine (XmlSerializer, nothing strange), the serialization of DataScenario causes its MyData property items to produce Xmlelement names from the base class name:
<DataScenario>
<MyData>
<ScenarioData/>
<ScenarioData/>
<ScenarioData/>
</MyData>
<DataScenario>
Instead, i'm trying to have these items produce XmlElement names from their derived classes
<DataScenario>
<MyData>
<type1/>
<type1/>
<type2/>
</MyData>
<DataScenario>
Is this even possible? Keep in mind I need to deserialize as well; I'm unsure whether the Deserialize process will understand that derived objects need to be created.
Sample code i'm using is as follows.
[Serializable]
[XmlInclude(typeof(Type1))]
[XmlInclude(typeof(Type2))]
public class Scenario
{
[XmlElement("location")]
public string Location { get; set; }
[XmlElement("value")]
public string Value { get; set; }
public Scenario()
{
}
}
[Serializable]
[XmlType("type1")]
public class Type1 : Scenario
{
public FillPointData() : base() { }
}
[Serializable]
[XmlType("type2")]
public class Type2 : Scenario
{
public TestData() : base() { }
}
//Hosting class of all scenarios
public DataScenario()
{
public List<Scenario> MyData{ get; set; }
}
You can define what kind of Elements are in the Collection with the XmlArrayItem attribute.
If the Type is known (defined as you did with the XmlInclude attribute) it will create Tags "Type1", "Type2". If the Types are not known, it will still create a Tag called ScenarioData with an Attribute xsi:type="Type1" which is used to map the type while deserialization.
[XmlArrayItem(typeof(Type1))]
[XmlArrayItem(typeof(Type2))]
Public List<Scenario> Children
{
// getter & setter
}

Categories

Resources