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.
Related
Currently I am building some functionality that takes an object (in my case a blog post) in JSON format and validates it meets the 'Post' schema before deserializing it into an object. This is my current solution -
{
const string rawPost = #"{
""userId"": 1,
""id"": 200,
""title"": ""hello"",
""body"": ""body""
}";
JSchemaGenerator generator = new JSchemaGenerator();
JSchema schema = generator.Generate(typeof(Post));
var isPost = IsValid(JObject.Parse(rawPost), schema);
if (isPost)
{
var post = JsonConvert.DeserializeObject<Post>(rawPost);
}
}
public static bool IsValid(JObject jObject, JSchema jSchema)
{
return jObject.IsValid(jSchema);
}
public class Post
{
public int userId { get; set; }
public int id { get; set; }
public string title { get; set; }
public string body { get; set; }
}
}
Currently I do not like the fact that my 'Post' object in this case has incorrectly cased properties and breaks normal conventions - Which means the object is not very reusable. Is there another way of achieving the same thing with Pascal Casing?
You could decorate the properties of your class with the NewtonSoft JsonProperty attribute, setting the PropertyName as follows:
using Newtonsoft.Json;
public class Post
{
[JsonProperty(PropertyName = "userId")]
public int UserId { get; set; }
[JsonProperty(PropertyName = "id ")]
public int Id { get; set; }
[JsonProperty(PropertyName = "title ")]
public string Title { get; set; }
[JsonProperty(PropertyName = "body ")]
public string Body { get; set; }
}
The JsonSerializer object will use these in its deserialization.
Edit: or as per the linked duplicate question
I have following json coming from server
{
"contactList":[{
"contactName":"Jhon",
"address":null,
"phone":null,
"contactId":99932
}]
}
now when i am deserializing using JsonConvert.DeserializeObject<Response>(content) i want following output
{
"contactList":[{
"contactName":"Jhon",
"contactId":99932
}]
}
i tried following code but its not working
JsonSerializerSettings jsonSettings = new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Ignore,
MissingMemberHandling = MissingMemberHandling.Ignore
};
this is my Contact model
public class Contact
{
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public String address { set; get; }
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public String phone { set; get; }
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public String name { set; get; }
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public String id { set; get; }
}
model of Response
[JsonObject(MemberSerialization = MemberSerialization.OptIn)]
public class Response
{
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public IList<SignodeMSA.Model.Master.Contact> contactsList { get; }
}
and i am deserializing after fetching it from server
Response responseData = await Task.Run(() => JsonConvert.DeserializeObject<Response>(content, jsonSettings));
I think you need manually delete that properties from json string.
Maybe like this : How do I remove all null and empty string values from a json object?
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.
I'm using Asp.Net, and although I've done some work deseriaizing Xml before, I've not got to do the same with json.
The error I'm getting is Data at root level is invalid, something I've seen before with Xml deserialization.
Here's the documentation I have for the response:
HTTP ResponseCode: 200
HTTP Status: OK
HTTP Body:
{
“Status”:”Success”,
“Response”:”0”,
“Price”:”10.00”,
“BuyerId”:999,
“BuyerContractId”:9999,
“Detail”:”https://...”
}
I'm using a WebClient to get the data back:
response = wc.UploadString(info.Endpoint, info.Data);
"response" is a string. I use this method to deserialize:
public static T JsonResponse<T>(string response)
where T : class
{
var s = new DataContractJsonSerializer(typeof(T));
using (var r = XmlReader.Create(new StringReader(response)))
{
return (T)s.ReadObject(r);
}
}
The class I'm trying to deserialize to is:
[DataContract]
public class ResponseProps
{
[DataMember(Name = "Status")]
public string Status { get; set; }
[DataMember(Name = "Response")]
public string Response { get; set; }
[DataMember(Name = "Price")]
public decimal Price { get; set; }
[DataMember(Name = "BuyerId")]
public string BuyerId { get; set; }
[DataMember(Name = "BuyerContractId")]
public string BuyerContractId { get; set; }
[DataMember(Name = "Detail")]
public string Detail { get; set; }
}
Here's how it's called:
var cr = XmlHelper.JsonResponse<ResponseProps>(response);
Anyone got any clues as to where I'm going wrong?
Assuming the data comes in JSON format, I changed the following -
public static T JsonResponse<T>(string response)
where T : class
{
return JsonConvert.DeserializeObject<T>(response);
}
Now this works fine-
var q = JsonResponse<ResponseProps>('jsonString');
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