Deserialize list of objects in C# - c#

I Use JsonConvert to serialize an object and save it in a database. This is a sample of the serialized string that I saved in database:
[{"matId":"1","value":"44"},{"matId":"2","value":"55"},{"matId":"4","value":"77"}]
Now when I get this string from database which has a lot of backslashes like this:
"[{\"matId\":\"1\",\"value\":\"44\"},{\"matId\":\"2\",\"value\":\"55\"},{\"matId\":\"4\",\"value\":\"77\"}]"
And for this reason I can't Deserialize it.
.Replace("\\","") method doesn't create any affect on this. I don't know why.

You have to use JsonConvert.Deserialize method.
Your json string is wrapped within square brackets ([]), hence it is interpreted as array. Therefore, you need to deserialize it to type collection of one class, for example let's call it MyClass.
public class MyClass
{
public int matId { get; set; }
public int value { get; set; }
}
Here is Deserialize method.
var results=JsonConvert.DeserializeObject<List<MyClass>>(json);

Backslashes represent serialized object.
You need to deserialize your List object.
You can try using Generics:
public List<T> Deserialize<T>(string path)
{
return JsonConvert.DeserializeObject<List<T>>(path);
}

Be careful when looking at json strings as you are debugging. In Visual Studio it needs to format the value into a string. To do that it will add " so that it can process it when actually the value does not contain them. That is why the replace does not work.

Related

Accessing properties with a dot in their name

I am trying to deserialize JSON. My root object has a single property "en.pickthall". I am using dynamic type for reading my JSON. I thought I could just do away with "." in the property since its a local JSON file but then there must be some way to access such a property
var result = App_Code.FileIOHelper.ReadFromDefaultFile("ms-appx:///Assets/en.pickthall.json");
dynamic stuff = JsonConvert.DeserializeObject(result);
foreach(var x in stuff.(en.pickthall)) //Tried this intellisense didn't like it
{
}
You could create a root class to deserialize into and use JsonProperty
public class Root
{
// Use the proper type instead of object
[JsonProperty(PropertyName = "en.pickthall")]
public IEnumerable<object> EnPickthall { get; set; }
public Root() { }
}
Used as follows
Root stuff = JsonConvert.DeserializeObject<Root>(result);
foreach(var x in stuff.EnPickthall)
{
}
You could serialize not to dynamic but to JObject and then access your property via
JObject stuff = JsonConvert.DeserializeObject<JObject>(Jsonstring);
var x = stuff.Value<String>("my.property")
C# doesn't have any way of quoting identifiers. If it's not a valid identifier, your only option is reflection.
However, it's possible the object returned by your JSON deserializer changed the identifiers to make them useable in C# - you might want to enumerate all the properties to check if that is the case. A dynamic object with indexers might also be a solution (allowing e.g. stuff["en.pickthall"]).
Another alternative is to change the way the serializer maps properties. For example, Newtonsoft.Jsoft allows you to customize this using a IContractResolver. It's quite easy to replace the . for something more C#-sane in this way.
I know you said you were using a dynamic type for your JSON deserialization, but I just wanted to point out that there is a .NET RESTful client out there that supports this with static model definitions too. For you or for anyone else who happens upon this response when searching for an answer to their problems with dots in property names in C# REST calls.
As of the newly released RestSharp 106.1.0 (and I do mean this version because this support was just added), it can handle renaming properties with a dot in their name via the DeserializeAs attribute. An example being when I call the ElasticSearch API for a _cat call with the following model:
public class CatResponse
{
public string index { get; set; }
...
[DeserializeAs(Name = "docs.count")]
public string docscount { get; set; }
}
And actually get back the docs.count property deserialized into docscount now:
var resource = $"_cat/indices/{indexPattern}?format=json&pretty=true";
var request = new RestRequest(resource, Method.GET);
var response = client.Execute<List<CatResponse>>(request);
This support is out of the box and doesn't need to use the Newtonsoft.Json.JsonSerializer which I have also heard is a possible solution to this problem but which I couldn't get to work.
With a dynamic object and NewtonSoft.Json:
dynamic json = JValue.Parse(result);
int Opens = Convert.ToInt32(json.opens);
int Clicks = Convert.ToInt32(json.clicks);
string State = json.state;

How can you deserialize a JSON array containing different types in .Net?

I'm trying to deserialize a JSON object array in C#. The array represents a row of a table, mainly consisting of plain strings. However, one or more of the items in the array may not be a string but infact a JSON object in itself, e.g.
"rows":[[{"date":"20140521","category":"one"},"data","moredata","evenmoredata"],...]
or on a different response from the server, the order may be different
"rows":[["data","moredata",{"date":"20140521","category":"one"},"evenmoredata"],...]
I'm trying to just treat this as a list of objects, with a known type called RowObject below:
[DataContract]
[KnownType(typeof(RowObject))]
public class Table
{
// other members to deserialize
[DataMember(Name = "rows")]
public List<List<object>> Rows { get; set; }
}
[DataContract]
public class RowObject
{
[DataMember(Name = "date")]
public DateTime date { get; set; }
[DataMember(Name = "category")]
public string category { get; set; }
}
This approach kind of worked in that the plain strings in the row were deserialized, however the RowObjects do not seem to be recognised even though I have tried to put them down as a KnownType. When I look at my deserialized List<object> Row, the RowObject just seems to be a blank object shown as {object} in the debugger.
I've managed to do this with known types and derived types elsewhere in the project but this problem dealing with plain strings has got me stuck. I've had a look at this question which seems pretty similar, but my problem with this answer is that I don't know which elements in the list are going to be the complex type. Also, I'm just using the .Net DataContractJsonSerializer throughout the project so would like to avoid third party libraries if at all possible.
Is it possible to deserialize a JSON array of different types like this?
Set EmitTypeInformation in DataContractJsonSerializerSettings to EmitTypeInformation.Always on the server side. That way you will get information about the types of your objexts, inside the json string.

Deserialization of JSON object by using DataContractJsonSerializer in C#

I'm sure this question has been asked over and over again, but for some reason, I still can't manage to get this to work.
I want to deserialize a JSON object that contains a single member; a string array:
[{"idTercero":"cod_Tercero"}]
This is the class that I'm trying to deserialize into:
[DataContract]
public class rptaOk
{
[DataMember]
public string idTercero { get; set; }
public rptaOk() { }
public rptaOk(string idTercero)
{
this.idTercero = idTercero;
}
}
This is the method that I try to deserialize:
public T Deserialise<T>(string json)
{
DataContractJsonSerializer deserializer = new DataContractJsonSerializer(typeof(T));
using (MemoryStream stream = new MemoryStream(Encoding.Unicode.GetBytes(json)))
{
T result = (T)deserializer.ReadObject(stream);
return result;
}
}
And so I try to fill the object:
rptaOk deserializedRpta = deserializarOk(rpta);
But for some reason, this returns ""
MessageBox.Show(deserializedRpta.idTercero);
Without any dependencies outside of the .net framework, you could do it this way
[DataContract(Name="rptaOk")]
public class RptaOk
{
[DataMember(Name="idTercero")]
public string IdTercero { get; set; }
}
[CollectionDataContract(Name="rptaOkList")]
public class RptaOkList : List<RptaOk>{}
var stream = new StreamReader(yourJsonObjectInStreamFormat);
var serializer = new DataContractSerializer(typeof(RptaOkList));
var result = (RptOkList) serializer.ReadObject(stream);
I don't know if your're wiling to change the library that you're using, but I use library "Newtonsoft.Json" to desserialize JSON objects, it's pretty easy to use
[HttpPost]
public void AddSell(string sellList)
{
var sellList = JsonConvert.DeserializeObject<List<Sell>>(sellListJson);
BD.SaveSellList(sellList);
}
As you can see you can deserialize a whole json object list to a List<> fo the type "Sell", an object that i've created... And, of course, you can do that to an array too. I don't know the correct syntax for this, but you can convert this list to an array afterwards
Hope this helps
I think you're making this a lot more difficult than it needs to be. Firstly, your sample json and the class you're trying to deserialize into do not have an array of strings. They have a single property of type string. Secondly, why are you using this class DataContractJsonSerializer? You're not doing anything with it that you can't get from a simple call to json.NET's generic deserialization method. I would remove all of your code except the class definition and replace it with this simple one liner;
rptaOk[] myInstances = JsonConvert.DeserializeObject<rptaOk>(jsonString);
Also, no matter what the structure of your json is, if you have a class to correctly model it that method will correctly deserialize it. If you want to enforce some kind of contract I recommend using json schemas which json.NET also supports. If you use a schema it enforces a rigid contract, if you attempt to deserialize into an object there is something of an implicit contract. I don't know every scenario which will cause it to throw, but if your json is too far from the class definition it will. If your class has properties that don't appear in the json I believe they will just get initialized with the default values for that type.
EDIT: I just noticed your json is actually an array of objects. So you simply need to make the lhs of that assignment an array or rptaOk objects, rather than a singleton.

Deserialize object binary to XML?

I am having some trouble deserializing an object to XML. I am trying to deserialize something which doesn't have an empty constructor thus I need to use the BinaryFormatter? I have:
A DLL which consists of a class I want to deserialize into XML.
From reflecting the type I can see that it has no parameterless constructor.
This class contains properties of which some do not have empty constructors either.
My question is, is it possible to deserialize this class into XML? I did find a way whereby I used:
BinaryFormatter
Loaded the contents into a stream
Used a FileStream to write its contents but ended up with rubbish
Thanks in advance. I found something called FormatterServices... but don't know whether you could use this in conjunction with the XmlSerializer?
Deserialize the binary data back into an object.
Copy your object into a surrogate object.
Xml serialize your surrogate object.
Assume the type of your original non-xml serializable object is "Foo"
[XmlRoot]
public class FooSurrogate {
public FooSurrogate() { }; // note the empty constructor for xml deserialization
public FooSurrogate(Foo foo) { // this constructor is used in step 2
// in here you copy foo's state into this object's state
this.Prop1 = foo.Prop1; // this prop can be copied directly
this.Bar = new BarSurrogate(foo.Bar); // this prop needs a surrogate as well
}
[XmlAttribute] // note your surrogate can be used to xml-format too!
public string Prop1 { get; set; }
[XmlElement]
public BarSurrogate Bar { get; set; }
}
public class BarSurrogate {
...
}

Deserialize json array data in c# [duplicate]

I need to deserialize some JavaScript object represented in JSON to an appropriate C# class. Given the nice features of automatic properties, I would prefer having them in these classes as opposed to just having fields. Unfortunately, the .NET serialization engine (at least, by default) totally ignores automatic properties on deserialization and only cares about the backing field, which is obviously not present in the JavaScript object.
Given that there's no standard way to name backing fields and to be honest I don't even want to bother with the "let's create a JavaScript object that looks like it had C# backing fields" approach as it sounds a bit dirty, the only way I could serialize JavaScript fields to C# auto-properties if I could force the serialization engine to somehow ignore the backing field and use the property directly. Unfortunately, I can't figure out how this is done or if this can be done at all. Any ideas would be appreciated.
EDIT: Here's an example:
Javascript:
function Cat()
{
this.Name = "Whiskers";
this.Breed = "Tabby";
}
var cat = new Cat();
This is then serialized to "{Name: 'Whiskers'}".
The C# class:
[Serializable()]
public class Cat
{
public string Name { get; set; }
public string Breed { get; set; }
}
And the deserialization code, that fails:
new DataContractJsonSerializer(typeof(Cat)).ReadObject(inputStream);
And it is apparent from the exception that it fails because it is looking for the backing field.
EDIT2: Here's the exception, if that helps (no inner exceptions):
System.Runtime.Serialization.SerializationException
"The data contract type 'Test.Cat'
cannot be deserialized because the
required data members
'<Name>k__BackingField, <Breed>k__BackingField' were not
found."
What's happening here is the deserializer is trying to guess the name of your backing fields.
You can solve this by adding explicit mappings (DataContract/DataMember attributes) like this:
[DataContract]
public class Cat
{
[DataMember]
public string Name { get; set; }
[DataMember]
public string Breed { get; set; }
}
You can do this with JavaScriptSerializer found in the System.Web.Script.Serialization namespace:
JavaScriptSerializer serializer = new JavaScriptSerializer();
Cat c = serializer.Deserialize<Cat>(jsonString);
I have POCO objects with automatic properties and this works just fine.
EDIT: I wrote about JSON Serializers in .NET which compares this serializer with DataContractJsonSerializer.
baretta's answer solved the k__BackingField bloat for me. Just a tiny addendum that you can decorate this class to auto serialize into either XML or JSON in a similar way:
[Serializable, XmlRoot, DataContract]
public class Cat
{
[XmlElement]
[DataMember]
public string Name { get; set; }
[XmlElement]
[DataMember]
public string Breed { get; set; }
}
... and then use a DataContractJsonSerializer or XmlSerializer to prepare it for your endpoint.
I'm assuming you are passing data via a web service. If you are using the WebService class with the ScriptMethod attribute uncommented-out, the web service methods can read JSON natively. They even use the same JavaScriptSerializer that was mentioned above. If you are using WCF I'm a little more fuzzy on the logic.
But make sure your JSON object are returning data for EVERY property in your class. In your error, there is mention of a Breed property that is not in your example.
Also, on the JavaScript side, do to the dynamic nature of JavaScript it is easy to add new properties to your objects. This can sometimes lead to circular references. You should remove any extra data that you might have added (just as you are sending data via the web method, then add it again once you are done).

Categories