Deserialize JSON to Custom Class - Object is null - c#

I have an AJAX call that sends the following JSON to my webservice:
{"Tags":["12","5","2"],"TargetId":"36946","TargetType":"Officer"}
Here's the webservice and custom class:
[WebMethod]
public string UpdateTags(string PostParameters)
{
JavaScriptSerializer serializer = new JavaScriptSerializer();
var tagData = serializer.Deserialize<TagData>(PostParameters);
// do some stuff with tagData
}
[Serializable]
[DataContract(Name = "PostParameters")]
public class TagData
{
[DataMember(Name = "TargetId")]
string TargetId { get; set; }
[DataMember(Name = "TargetType")]
string TargetType { get; set; }
[DataMember(Name = "Tags")]
List<int> Tags { get; set; }
}
Unfortunately, the properties of tagData are null. What am I not doing correctly?

Properties in TagData are not public. Make them public and it should work.
Also I would suggest using JSON.NET. It is faster.

Related

Deserializing a JSON to c# object when key contains dollar($)(Metadata)

So i'm getting a response like this
{"$id":"1","success":true,"errors":{"$id":"2","$values":[]}}
how can i convert this into to a c# object, tried using this(http://json2csharp.com/) tool to make an output but it doesn't make sense
this is what i'm getting
x
public class Errors
{
public string __invalid_name__$id { get; set; }
public List<object> __invalid_name__$values { get; set; }
}
public class RootObject
{
public string __invalid_name__$id { get; set; }
public bool success { get; set; }
public Errors errors { get; set; }
}
I'm kinda new to c#, any inputs would be deeply appreciated, i basically need access to success key variable
You need to add [JsonProperty] attribute to every property that key name started with dollar $
public class Errors
{
[JsonProperty("$id")]
public string id { get; set; }
[JsonProperty("$values")]
public List<object> values { get; set; }
}
public class RootObject
{
[JsonProperty("$id")]
public string id { get; set; }
public bool success { get; set; }
public Errors errors { get; set; }
}
Because the $ indicates metadata, not an actual data field. so you have to modify your JsonSerializerSettings to ignore MetadataPropertyHandling.
JsonSerializerSettings settings = new JsonSerializerSettings();
settings.MetadataPropertyHandling = MetadataPropertyHandling.Ignore;
And finally deserialize your json to above class objects.
RootObject rootObject = JsonConvert.DeserializeObject<RootObject>(json, settings);
Here I created a sample console app for demonstration purpose that shows how above code will work.
class program
{
public static void Main()
{
string json = File.ReadAllText(#"Path to your json file");
JsonSerializerSettings settings = new JsonSerializerSettings();
settings.MetadataPropertyHandling = MetadataPropertyHandling.Ignore;
RootObject rootObject = JsonConvert.DeserializeObject<RootObject>(json, settings);
Console.WriteLine("id: " + rootObject.id);
Console.WriteLine("success: " + rootObject.success);
Console.WriteLine("errors.id: " + rootObject.errors.id);
Console.WriteLine("errors.values: " + string.Join(",", rootObject.errors.values));
Console.ReadLine();
}
}
Output:
Well, What you can do is
public class Errors
{
[JsonProperty(PropertyName = "$id")]
public string id { get; set; }
[JsonProperty(PropertyName = "$values")]
public List<object> values { get; set; }
}
public class RootObject
{
[JsonProperty(PropertyName = "$id")]
public string id { get; set; }
public bool success { get; set; }
public Errors errors { get; set; }
}
You need your object attributes to match you json string ($id instead of _invalid_name_$id), then you can use:
JsonConvert.DeserializeObject<RootObject>(jsonString);
Here is a simple class to serialize json string from object or to object (T). May de/serialize array(list) of objects.
public class HelperSerializer<T> where T: class
{
public static string WriteFromObject(T source)
{
using (var ms = new MemoryStream()) {
var ser = new DataContractJsonSerializer(typeof(T));
ser.WriteObject(ms, source);
byte[] json = ms.ToArray();
return Encoding.UTF8.GetString(json, 0, json.Length);
}
}
// Deserialize a JSON stream to an object.
public static T ReadToObject(string json)
{
using (var ms = new MemoryStream(Encoding.UTF8.GetBytes(json)))
{
var ser = new DataContractJsonSerializer(typeof(T));
return ser.ReadObject(ms) as T;
}
}
}
Use persons = HelperSerializer<List<Person>>.ReadToObject(json);
and var json = HelperSerializer<List<Person>>.WriteFromObject(persons);

Unable to get specific string from Json C#

This is how my json looks like:
I created the following code:
public class user
{
public string username { get; set; }
public int userid
{
get;
set;
}
public string red
{
get;
set;
}
public string acompaccompelted_setup
{
get;
set;
}
}
To get the data from URL I used the following code:
string url = "localhost/testingdata/file.json";
HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
string jsonValue = "";
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
StreamReader reader = new StreamReader(response.GetResponseStream());
json = reader.ReadToEnd();
}
user listing = JsonConvert.DeserializeObject<user>(json);
Console.WriteLine(listing.username);
Console.ReadLine();
Unfortunately, I'm not able to get the value for the string "username". It returns an empty value. If I try to use :
List<user> items = JsonConvert.DeserializeObject<List<user>>(json);
Then I'm getting another error. If I call the:
Console.WriteLine(json);
Then I'm getting the complete list of JSON. But I want to extract the username only. I tried to follow steps given here https://www.c-sharpcorner.com/article/working-with-json-in-C-Sharp/ but with no success. What I'm doing wrong?
Define a wrapper UserInfo class to represent the whole object as follows:
class UserInfo
{
[JsonProperty(PropertyName = "user", NullValueHandling = NullValueHandling.Ignore)]
public User User { get; set; }
}
Define the User class as follows:
class User
{
[JsonProperty(PropertyName = "userName", NullValueHandling = NullValueHandling.Ignore)]
public string UserName { get; set; }
[JsonProperty(PropertyName = "userId", NullValueHandling = NullValueHandling.Ignore)]
public long UserId { get; set; }
[JsonProperty(PropertyName = "accompletedSetup", NullValueHandling = NullValueHandling.Ignore)]
public string AccompletedSetup { get; set; }
[JsonProperty(PropertyName = "accompletedInfo", NullValueHandling = NullValueHandling.Ignore)]
public AccompletedInfo AccompletedInfo { get; set; }
}
The accompletedInfo property is a complex object. So define a new class to represent it as follows:
class AccompletedInfo
{
}
Follow the same pattern for all the nested objects. i.e. define a class for each nested object with properties and name of the property in the JsonProperty attribute.
Then deserialize using JsonConvert as follows:
var user = JsonConvert.DeserializeObject<UserInfo>(json);
The object user now has all the properties as expected.

How to Deserialize an xml element with only attributes in C#?

I am using System.Xml.Serialization.XmlSerializer class.I need to Deserialize the following XML in C#:
<message from="abc" to="xyz" xml:lang="en" id="Vx4Ix-14" type="chat">
<received xmlns="urn:xmpp:receipts" id="9beea4d7-aa1e-4f3c-929c-712b56164b63"/>
</message>
Following is my Class to deserialize it :
[XmlRoot(ElementName = "message")]
public class Message
{
[XmlAttribute(AttributeName = "type")]
public string Type { get; set; }
[XmlAttribute(AttributeName = "from")]
public string From { get; set; }
[XmlAttribute(AttributeName = "to")]
public string To { get; set; }
[XmlAttribute(AttributeName = "id")]
public string Id { get; set; }
[XmlAttribute(AttributeName = "xml:lang")]
public string Language { get; set; }
[XmlElement(ElementName = "received", Namespace = "urn:xmpp:receipts")]
public Received Received { get; set; }
}
public class Received
{
[XmlAttribute(AttributeName = "id")]
public string Id { get; set; }
}
The "received" xml element has only attributes and I want te deserialize that element to get "id" value of that element.
But when I use the above class to Deserialize , I get all the values except "id" attribute value of "received" xml element. I get the value of Received property as null.
Please let me know what is wrong with my class?
This is my Deserializer Method:
public static T Deserialize<T>(string xml)
{
T deserializedObject = default(T);
try
{
var serializer = new XmlSerializer(typeof(T));
using (var memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(xml)))
{
deserializedObject = (T)serializer.Deserialize(memoryStream);
}
return deserializedObject;
}
catch (Exception)
{
return deserializedObject;
}
}
Your class looks good and also works for me. Maybe you're not using the deserializer correctly!? I successfully tried it with your XML like this:
var serializer = new XmlSerializer(typeof(Message));
var message = (Message)serializer.Deserialize(
new FileStream(#"C:\Users\homann.k\Desktop\test.xml", FileMode.Open, FileAccess.Read));

Parse JSON in response to the existing request

Hi I have a response from the web service and i would like to have a single url from the response.
My response is in the below format.
[{"cdn_streaming_uri": "9e849cfbb2e157-22558a0600b387d0abe240fe5.r73.stream..rackcdn.com", "name": "test1", "cdn_ios_uri": "d3d4c27-22558a0600b387d0abc071d0ae240kcdn.com", "cdn_ssl_uri": "https://990fea26e-22558a0600b387d0abc071d0ae240fe5.ssl.cdn.com", "cdn_enabled": false, "ttl": 259200, "log_retention": false, "cdn_uri": "99b56a009-22558a0600b3c071d0ae240fe5.r73.n.com"}, {"cdn_streaming_uri": "74ec8c-d5edc6cad91792413b1b134fde.r46.stcdn.com", "name": "test2", "cdn_ios_uri": "d05437e44-d5edc61792413b1b134fde.iosr.cdn.com", "cdn_ssl_uri": "https://a1c2ebbf5-d5edc6cd91792413b1b134fde.scdn.com", "cdn_enabled": false, "ttl": 259200, "log_retention": false, "cdn_uri": "72ffd-d5edc6ca16852413b1b134fde.cdn.com"}, {"cdn_streaming_uri": "93665b76-550971032c2a22cdn.com", "name": "test3", "cdn_ios_uri": "ca6b-550971032c2fbf19452d6a.iosr.cf2.rackcdn.com", "cdn_ssl_uri": "https://c7c39-550971032cbf19452d6cdn.com", "cdn_enabled": true, "ttl": 86400, "log_retention": true, "cdn_uri": "68fc6d831a94-550971032c252d6a.r3cdn.com"}]
I need to the "cdn_streaming_uri" for the name "test3".
You can view the JSON parser in http://json.parser.online.fr/
How do i parse it?
Here is my code:
public static object getTokenResponse(String PrivateURL, string ResponseType)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(PrivateURL +"?format=JSON");
request.Method = "GET";
request.Headers.Add("X-Auth-Token", id);
//request.ContentType = "application/XML";
HttpWebResponse resp1;
try
{
resp1 = (HttpWebResponse)request.GetResponse();
}
catch (Exception exp)
{
string[] st = new string[0];
return st;
}
StreamReader reader = new StreamReader(resp1.GetResponseStream());
string secondresponse = reader.ReadToEnd();
Console.WriteLine(secondresponse);
reader.Close();
JavaScriptSerializer json_serializer = new JavaScriptSerializer();
object obj1 = json_serializer.DeserializeObject(secondresponse);
}
I could see the response in obj1.
The best approach, I think, is to create class which will represent your response. The easiest way is to use Visual Studio's EDIT -> Paste Special -> Paste JSON As Classes option:
You just copy your response and paste it as JSON classes. Visual studio will generate model for you. In this particular case the result will be:
namespace ConsoleApplication91
{
public class Rootobject
{
public Class1[] Property1 { get; set; }
}
public class Class1
{
public string cdn_streaming_uri { get; set; }
public string name { get; set; }
public string cdn_ios_uri { get; set; }
public string cdn_ssl_uri { get; set; }
public bool cdn_enabled { get; set; }
public int ttl { get; set; }
public bool log_retention { get; set; }
public string cdn_uri { get; set; }
}
}
which, of course, does not look very nice, but you're always welcome to refactor this code. When you have your model you download your response, parse it and get what you need using linq, for example:
using (var client = new WebClient())
{
var url = "your service url";
var serializer = new JavaScriptSerializer();
// Response in JSON format
var respJson = client.DownloadString(url);
// Deserialized response
var resp = serializer.Deserialize<Rootobject>(respJson);
// Your requested result
var result = resp.Property1.FirstOrDefault(o => o.name == "test3").cdn_streaming_uri;
}
EDITS:
After refactoring (using DataMember attributes and removing redundant model objects) you can have the following model:
[DataContract]
public class Model
{
[DataMember(Name = "cdn_streaming_uri")]
public string CdnStreamingUri { get; set; }
[DataMember(Name = "name")]
public string Name { get; set; }
[DataMember(Name = "cdn_ios_uri")]
public string CdnIosUri { get; set; }
[DataMember(Name = "cdn_ssl_uri")]
public string CdnSslUri { get; set; }
[DataMember(Name = "cdn_enabled")]
public bool CdnEnabled { get; set; }
[DataMember(Name = "ttl")]
public int Ttl { get; set; }
[DataMember(Name = "log_retention")]
public bool LogRetention { get; set; }
[DataMember(Name = "cdn_uri")]
public string CdnUri { get; set; }
}
After some research I've figured out that JavascriptSerializer is a little deprecated and it does not support any kind of DataMemberAttributes. So I would recommend to use DataContractJsonSerializer. It is little messier than JavascriptSerializer but I think it's fine. If you do not care about any code conventions you can peacefully use the firs provided option (with JavaScriptSerializer and no DataMember attributes). And do not forget to update result query:
using (var ms = new MemoryStream(Encoding.Unicode.GetBytes(respJson)))
{
var serializer = new DataContractJsonSerializer(typeof(Model[]));
var resp = serializer.ReadObject(ms) as Model[];
var result = resp.FirstOrDefault(o => o.Name == "test3").CdnStreamingUri;
}
But, also, if you don't want to use linq (which I'm still strongly recommend) you can create some function which will find the CdnStreamingUri you need:
public static class Extensions
{
public static string GetCdnStreamingUriFor(this Model[] input, string name)
{
foreach (var model in input)
{
if (model.Name == name)
return model.CdnStreamingUri;
}
return string.Empty;
}
}
And your result query will look like:
var result = resp.GetCdnStreamingUriFor("test3");
P.S.
Full list of all used namespaces:
using System;
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Json;
using System.Text;
using System.Runtime.Serialization;
I recommend you to generate class for that json, like the following (http://json2csharp.com/ ):
public class RootObject
{
public string cdn_streaming_uri { get; set; }
public string name { get; set; }
public string cdn_ios_uri { get; set; }
public string cdn_ssl_uri { get; set; }
public bool cdn_enabled { get; set; }
public int ttl { get; set; }
public bool log_retention { get; set; }
public string cdn_uri { get; set; }
}
After that you can deserialize strongly typed object http://msdn.microsoft.com/en-us/library/bb355316(v=vs.110).aspx

How to deserialize JSON string is correct in c#?

Help to deal with JSON deserialization correct answer. For example, we have JSON response to the following:
{"variant":"otvet1",
"source":"otvet2",
"items":[
{"list":"512"},
{"vist":"315"},
{"zist":"561"}]}
To deserialize using the following code:
[DataContract]
public partial class ItemsList
{
[DataMember(Name = "list")]
public string lisType { get; set; }
[DataMember(Name = "vist")]
public string vistType { get; set; }
[DataMember(Name = "zist")]
public string zistType { get; set; }
}
[DataContract]
public partial class SourceList
{
[DataMember(Name = "variant")]
public string variantType { get; set; }
[DataMember(Name = "source")]
public string vistType { get; set; }
[DataMember(Name = "items")]
public List <ItemsList> TestItemsList { get; set; }
}
public class JsonStringSerializer
{
public static T Deserialize<T>(string strData) where T : class
{
MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(strData));
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T));
T tRet = (T)ser.ReadObject(ms);
ms.Close();
return (tRet);
}
}
private static SourceList SourceTempList;
SourceTempList = JsonStringSerializer.Deserialize<SourceList>(e.Result); //in e.Result JSON response
In the previous code, it works, but if you change the JSON response, it does not work ...
New JSON response:
{"variant":"otvet1",
"source":"otvet2",
"items":[3,
{"list":"512"},
{"vist":"315"},
{"zist":"561"}]}
In this case, c # code for deserialization does not work ...
Items in the number 3 appeared, tell me how to deserialize the JSON response to this?
Were available to list vist and zist ...Help me...please
Historically the DataContractJsonSerializer has been seen as broken. The reccomendation is to use JSON.Net http://james.newtonking.com/projects/json-net.aspx
Check out Deserialization problem with DataContractJsonSerializer

Categories