This is the json string I need to deserialize:
[{"id":5236083584722820,"name":"IT_Projects","accessLevel":"EDITOR"},
{"id":2034305724639108,"name":"IT_Task","accessLevel":"EDITOR"},
{"id":2249810003683204,"name":"On-Hold","accessLevel":"EDITOR"}]
Here is the code:
[DataContract]
public class SSCollection
{
[DataMember]
public List<SSheets> sheetObjects { get; set; }
}
[DataContract]
public class SSheets
{
[DataMember]
public Int64 id { get; set; }
[DataMember]
public string name { get; set; }
[DataMember]
public string accessLevel { get; set;}
}
using (var memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(json)))
{
memoryStream.Position = 0;
var serializer = new DataContractJsonSerializer(typeof(SSCollection));
SSCollection ss = (SSCollection)serializer.ReadObject(memoryStream);
return ss;
}
I'm not sure how to handle the json string, it appears to be an array but is not named. I've tried with using the SSheets DataContract and with using SSCollection, both return nulls except when I use SSheets i get a 0 for id and nulls for the strings name and accessLevel. Any help will be greatly appreciated. thanks.
AFter reading many other questions on this subject and reading their sugggestions to use Json.Net I have decided to use Newtonsoft.Json. It worked on the first try. .Net DataContract just not worth the hassle. Thanks for your help.
Related
maybe this was asked somewhere before, but I don't know how to search for my problem.
I'm using a WebAPI to verify licenses. From this API I get the return JSON string in follwing format.
string json = "[{"status":"error","status_code":"e002","message":"Invalid licence key"}]"
This is my serializer
using (var ms = new MemoryStream(Encoding.Unicode.GetBytes(json)))
{
DataContractJsonSerializer js = new DataContractJsonSerializer(typeof(ActivationResponseWooSl));
ActivationResponseWooSl ar = (ActivationResponseWooSl)js.ReadObject(ms);
}
Now my questions is, how must the "ActivationResponseWooSl" class look like so that the serializer can convert it?
Any help is highly appreciated!
For now it looks like that (what's not workiing):
[DataContract]
public class ActivationResponseWooSl
{
[DataMember(Name = "status")]
public string Status { get; set; }
[DataMember(Name = "status_code")]
public string ErrorCode { get; set; }
[DataMember(Name = "message")]
public string ErrorMessage { get; set; }
}
However when I serialize my json string, all properties are "null".
Your class is correct. Your JSON is an array of object.
Try
DataContractJsonSerializer js = new DataContractJsonSerializer(typeof(ActivationResponseWooSl[]));
var arr = (ActivationResponseWooSl[])js.ReadObject(ms);
I don't want to use Newtonsoft's Json.Net library. I'm avoiding any third-party dependencies if I can help it in this project.
If I have JSON that looks like this:
{
"has_more_items": false,
"items_html": "...",
"min_position": "1029839231781429248"
}
and I have a class that looks like this:
public class TwitterJson
{
bool hasMore { get; set; } // has_more_items
string rawText { get; set; } // items_html
string nextKey { get; set; } // min_position
}
and I have a JsonObject containing the above JSON:
JsonObject theJson = JsonObject.Parse(result);
How do I deserialize the JsonObject into my class? I've been trying to find a clear example of this, and everything I've found uses Json.Net.
I've been trying to find a clear example of this, and everything I've found uses Json.Net.
Because reinventing existing functionality is a waste of time especially when all the hard work has already been done for you.
If you insist on not using it then you will have to manually construct the object model based on the expected JSON.
For example, assuming publicly available properties
public class TwitterJson {
public bool hasMore { get; set; } // has_more_items
public string rawText { get; set; } // items_html
public string nextKey { get; set; } // min_position
}
Then parsing the above to the desired object model
JsonObject theJson = JsonObject.Parse(result);
var model = new TwitterJson {
hasMore = theJson.GetNamedBoolean("has_more_items"),
rawText = theJson.GetNamedString("items_html"),
nextKey = theJson.GetNamedString("min_position")
};
As mentioned by #Dimith, you need to decorate your class with [DataContract] and [DateMember], Please refer to below code which will convert your JSON into a given object.
// Deserialize a JSON string to a given object.
public static T ReadToObject<T>(string json) where T: class, new()
{
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T));
using (MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(json)))
{
return ser.ReadObject(stream) as T;
}
}
Class:
[DataContract]
public class TwitterJson
{
[DataMember(Name = "has_more_items")]
bool hasMore { get; set; } // has_more_items
[DataMember(Name = "items_html")]
string rawText { get; set; } // items_html
[DataMember(Name = "min_position")]
string nextKey { get; set; } // min_position
}
Sample on how to use:
var result = "{\"has_more_items\": false, \"items_html\": \"...\",\"min_position\": \"1029839231781429248\"}";
var obj = ReadToObject<TwitterJson>(result);
You have to decorate your class with [DataContract] and [DataMember] attributes. Write the json into a memory stream and deserialize using DataContractJsonSerializer
Here is a more elaborated sample.
In addition to #Nkosi's answer below are some Comparisons between JSON.net and other alternatives:
JSON.Net vs DataContractJsonSerializer
JSON.Net vs Windows.Data.Json
I have a generic serializer and deserializer for messages that are sent over a network connection:
public static async Task<string> SerializeObject<T>(Object obj)
{
string objectStr;
using (var memStream = new MemoryStream())
{
DataContractSerializer serializer = new DataContractSerializer(typeof(T));
serializer.WriteObject(memStream, (T)obj);
memStream.Position = 0;
using (var sr = new StreamReader(memStream))
{
objectStr = await sr.ReadToEndAsync();
}
}
return objectStr;
}
public static async Task<T> DeserializeObject<T>(string obj)
{
using (var memStream = new MemoryStream())
{
byte[] data = System.Text.Encoding.UTF8.GetBytes(obj);
memStream.Write(data, 0, data.Length);
memStream.Position = 0;
DataContractSerializer serializer = new DataContractSerializer(typeof(T));
T result = (T)(serializer.ReadObject(memStream));
return result;
}
}
and I have a simple class that I serialize and deserialize. This is one of many classes like this, that's why I have the generic (de)serializer:
[DataContract]
public class SignatureMessage : NetworkMessage
{
[DataMember]
public string AppName { get; set; }
[DataMember]
public string AppUserName { get; set; }
[DataMember]
public string AppUserID { get; set; }
[DataMember]
public string IPAdress { get; set; }
[DataMember]
public string Port { get; set; }
}
When I set my project to 'Release' instead of 'Debug'. I get an XMLException EncounteredWithNameNamespaceExpectingElement. After research online, the suggestion was made to change my class to have an empty namespace in the datacontract element like this:
[DataContract(Namespace = "")]
public class SignatureMessage : NetworkMessage
{
[DataMember]
public string AppName { get; set; }
[DataMember]
public string AppUserName { get; set; }
[DataMember]
public string AppUserID { get; set; }
[DataMember]
public string IPAdress { get; set; }
[DataMember]
public string Port { get; set; }
}
When I tried this I got a different XMLException XmlPrefixBoundToNamespace. How can I apply the proper namespacing so both serializing and deserializing will work?
At first there were two things which catched my eyes:
You pass an Object to your SerializeObject method instead of the actual type T.
The empty namespace. This empty namespace tip is given in an MSDN article for visual basic. But still I'd ignore this tip and set the namespace to something unique and meaningful. Just remember: the namespace has to be the same on the client and the service for the same type.
If these two things won't help your cause you could possibly be running into a KnownType-Issue. Therefore I'd also recommend reading this article and utilizing the GenericResolver used in it.
Edit: Although my tips might not help you with your problem they are still true. But I noticed something in the full exception that you posted. http://schemas.datacontract.org/2004/07/ is the default namespace for a DataContract if none was specified explicitly. It could mean that you are trying to send something from Listen.Extensions. So this may also be a good starting point to look for possible errors.
I tried to reduce the problem. I put all code in one console application, removed the async and await keywords, removed the NetworkMessage inheritance and used public static async Task<string> SerializeObject<T>(T obj). No problems in debug and release mode. So look at the NetworkMessage implementation (not specified, not a .Net class I know) and be sure to use the same dll (with SignatureMessage and the other classes) on client and server.
I'm trying to deserialize json data with DataContractJsonSerializer class. a problem is how to set root element?
my json data is here.
{
"delete":{
"status":{
"id":696142765093072896,
"id_str":"696142765093072896",
"user_id":2223183576,
"user_id_str":"2223183576"
},
"timestamp_ms":"1454808363540"
}
}
and I wrote class for deserialization like this. but it isn't works. my Status always null.
[DataContract(Name="delete")]
public class Delete
{
[DataMember(Name="status")]
public DeletedStatus Status { get; set; }
}
public class DeletedStatus
{
[DataMember(Name = "id")]
public long Id { get; set; }
[DataMember(Name = "user_id")]
public long UserId { get; set; }
}
how can I start parse json from specific element?
Based on what I can tell from the JSON, the deserialization appears to be failing because the root property of the object is the "delete" property. I don't believe this will work with the DataContractJsonSerializer simply because the given type will not match the Delete type. One other possible issue is that I see the DeleteStatus class is missing a [DataContract] attribute.
Long story short, there is no simple way of doing what you want to do. That being said, there is a short and sweet way of deserializing the JSON without adding a lot of extra headache. I suggest creating a data type that represents the JSON in its current state, and deserialize to that type instead.
I wrote a Unit Test that you can run from a Visual Studio test project. I hope this helps.
JsonDeserializationTests.cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Runtime.Serialization.Json;
using System.IO;
namespace SerializationTests {
[TestClass]
public class JsonDeserializationTests {
[TestMethod]
public void Deserialize_Delete_Type_Success() {
string json = string.Empty;
//Set the DataContractJsonSerializer target type to our wrapper type.
var ser = new DataContractJsonSerializer(typeof(DeleteWrapperJsonResult));
//Create an instance of the wrapper that reflects the JSON that you gave.
//This will help me mock the data that you gave.
var deleteWrapper = new DeleteWrapperJsonResult {
delete = new DeleteJsonResult {
status = new DeletedStatusJsonResult {
id = 696142765093072896,
user_id = 2223183576
}
}
};
//Convert the mock data to JSON to reflect the JSON that you gave.
using (var serStream = new MemoryStream()) {
using (var sr = new StreamReader(serStream)) {
ser.WriteObject(serStream, deleteWrapper);
serStream.Position = 0;
json = sr.ReadToEnd(); //Set the JSON string here.
//Output "{\"delete\":{\"status\":{\"id\":696142765093072896,\"id_str\":\"696142765093072896\",\"user_id\":2223183576,\"user_id_str\":\"2223183576\"}}}"
}
}
//Prepeare to Deserialize the JSON.
var deserialized = default(DeleteWrapperJsonResult);
using (var deserStream = new MemoryStream()) {
using (var sw = new StreamWriter(deserStream)) {
sw.Write(json); //Write the JSON to the MemoryStream
sw.Flush();
deserStream.Seek(0, SeekOrigin.Begin);
//Deserialize the JSON into an instance of our wrapper class.
//This works because of the structure of the JSON.
deserialized = (DeleteWrapperJsonResult)ser.ReadObject(deserStream);
}
}
//Initialize the actual Delete instanace with what was deserialized.
var delete = new Delete {
Status = new DeletedStatus {
//These values were populated with the JSON values.
UserId = deserialized.delete.status.user_id,
Id = deserialized.delete.status.id
}
};
//Write asserts around what was given and check for equality.
Assert.AreEqual(delete.Status.UserId, deleteWrapper.delete.status.user_id);
Assert.AreEqual(delete.Status.Id, deleteWrapper.delete.status.id);
//Test Passes for Me
}
}
}
Delete.cs
using System.Runtime.Serialization;
namespace SerializationTests {
[DataContract]
[KnownType(typeof(Delete))]
public class Delete {
[DataMember]
public DeletedStatus Status { get; set; }
}
[DataContract]
[KnownType(typeof(DeletedStatus))]
public class DeletedStatus {
[DataMember]
public long Id { get; set; }
[DataMember]
public long UserId { get; set; }
}
/**************************************************************
These types below are what comprise our wrapper class so that we can
use the JSON in its current state. The wrapper classes have properties that
are synonymous with the JSON properties.
**************************************************************/
//This structure represents the object nesting as it appears currently in your example.
[DataContract]
[KnownType(typeof(DeleteJsonResult))]
public class DeleteWrapperJsonResult {
[DataMember]
public DeleteJsonResult delete { get; set; }
}
[DataContract]
[KnownType(typeof(DeleteJsonResult))]
public class DeleteJsonResult {
[DataMember]
public DeletedStatusJsonResult status { get; set; }
}
[DataContract]
[KnownType(typeof(DeletedStatusJsonResult))]
public class DeletedStatusJsonResult {
[DataMember]
public long id { get; set; }
[DataMember]
public string id_str {
get {
return id.ToString();
}
set {
return;
}
}
[DataMember]
public long user_id { get; set; }
[DataMember]
public string user_id_str {
get {
return user_id.ToString();
}
set {
return;
}
}
}
}
As of the time of this writing, my unit test is passing! Let me know if I can assist further.
I have seen some other questions like this, but those are quite complex JSON data's that have objects within objects. Although the JSON I'm working with is never static, I doubt it's as complex as those. Also, it's my first time using JSON with C# so I'm a little clueless.
What I'm trying to achieve is to separate the data that is received from an API that I prompt using WebRequest in C#.
{
"johhny.debt": {
"id":35187540,
"name":"johnny.debt",
"profileIconId":786,
"Level":30,
"revisionDate":1428019045000
}
}
The returned JSON data is in a fashion like thereof.
I want to be able to access all of the properties of the above string in the following manner:
ID :
Name:
~~
~~
~~
... and so forth.
I'm assuming some type of class has to be made for this?
All help is appreciated, thank you all in advance.
Install Json.Net from Nuget
Install-Package Newtonsoft.Json
https://www.nuget.org/packages/Newtonsoft.Json/
Declare class for inner object ({"id":..., "name": ... }):
public class InnerObject
{
[JsonProperty("id")]
public int Id { get; set; }
[JsonProperty("name")]
public string Username { get; set; }
[JsonProperty("profileIconId")]
public int ProfileIconId { get; set; }
[JsonProperty("level")]
public int Level { get; set; }
[JsonProperty("revisionDate")]
public string RevisionDate { get; set; }
}
As you can see you can specify rename mapping from json fields to .Net object properties using JsonPropertyAttribute.
Read your json to Dictionary<string,InnerObject> and get value of "johhny.debt" key:
var dict = JsonConvert.DeserializeObject<Dictionary<string, InnerObject>>(jsonText);
var johhny = dict["johhny.debt"];
Or if your need always to parse exact json property 'johhny.debt', you could create root object class:
public class RootObject
{
[JsonProperty("johhny.debt")]
public InnerObject JohhnyDept { get; set; }
}
And deserialize it:
var root = JsonConvert.DeserializeObject<RootObject>(jsonText);
var johhny = root.JohhnyDebt;
Just Create a class like this
public class RootObject
{
public int Id { get; set; }
public string name { get; set; }
public int profileIconId { get; set; }
public int Level { get; set; }
public string revisionDate { get; set; }
}
then install json.Net and this code to your main method
var jsonObject=JsonConvert.DeserializeObject<RootObject>(jsonText);
That's all
Update
var obj = JObject.Parse(json);
var RootObject = new RootObject()
{
Id = (int)obj["johhny.debt"]["id"],
Level = (int)obj["johhny.debt"]["Level"],
name = (string)obj["johhny.debt"]["name"],
profileIconId = (int)obj["johhny.debt"]["profileIconId"],
revisionDate = (string)obj["johhny.debt"]["revisionDate"]
};