I tried using json.net for converting json data into datatable, but am not able to solve, am newbie with json
code i tried:
string json = JsonConvert.SerializeObject(friend);
friends_info finfo = JsonConvert.DeserializeObject<friends_info>(json);
public class friends_info
{
public friends_info()
{
}
public string name_; // Backing field
public string name
{
get { return name_; } // Getter
set { name_ = value; } // Setter
}
public string id_; // Backing field
public string id
{
get { return id_; } // Getter
set { id_ = value; } // Setter
}
}
where string json="{"data":[{"name":"Angelina Jovy","id":"100000599264453"},{"name":"Luvbhie Rose May Aviles","id":"100001102845189"},{"name":"Nainy Ahuja","id":"100001103300515"},{"name":"Sabrina Reis","id":"100008357430263"}],"paging":{"next":"https://graph.facebook.com/v1.0/1539545690/friends?access_token=CAAGjOBYUDq0BAAFnIgfyfvMftE1ImSEfZCK7R7NdFYw5lnKuddHwqqlm20DTuZCjEeUh2hzMD0KAJpY1ozq3aPuh9nQUHBrXtG0Qu2sd6RwotUQtYj9jtGcMlJEzZCCBLLH8CZBSNQIZAzC2ASOxkYf3JCfwGZA7XSzF5y2iPVDWRCfrl8C4rZAZBzkJiaJwytVvSintYLRfySaunO81fAei&limit=5000&offset=5000&__after_id=enc_AewuVVCxM4Iz1IuazCHob3SZku3BDZ6NeU054UtCU_gc0QDAm2g2VNM__lcbuJNDtm9RmHLU-QCQifFun9H__Zqs"}}"
The class you're deserializing to must match the JSON string.
public class MyData
{
public friends_info[] data { get; set; }
public object paging { get; set; } // you can probably omit this
}
With that deserializing the given JSON string should work.
MyData myData = JsonConvert.DeserializeObject<MyData>(json);
friends_info finfo = myData.data;
Apart from that I'd very much suggest that you look into the C# basics again. Even that little code you posted violates the typical coding conventions.
i m not sure but i think your string is not in correct format it should be like this.
"{'data':[{'name':'Angelina Jovy','id':'100000599264453'},{'name':'Luvbhie Rose May Aviles','id':'100001102845189'},{'name':'Nainy Ahuja','id':'100001103300515'},{'name':'Sabrina Reis','id':'100008357430263'}],'paging':{'next':'https://graph.facebook.com/v1.0/1539545690/friends?access_token=CAAGjOBYUDq0BAAFnIgfyfvMftE1ImSEfZCK7R7NdFYw5lnKuddHwqqlm20DTuZCjEeUh2hzMD0KAJpY1ozq3aPuh9nQUHBrXtG0Qu2sd6RwotUQtYj9jtGcMlJEzZCCBLLH8CZBSNQIZAzC2ASOxkYf3JCfwGZA7XSzF5y2iPVDWRCfrl8C4rZAZBzkJiaJwytVvSintYLRfySaunO81fAei&limit=5000&offset=5000&__after_id=enc_AewuVVCxM4Iz1IuazCHob3SZku3BDZ6NeU054UtCU_gc0QDAm2g2VNM__lcbuJNDtm9RmHLU-QCQifFun9H__Zqs'}}";
if your json string is in correct format then #bstenzel suggestion should work fine.
Thanx
Related
Below is a (slightly) stripped down response I get from a REST API upon successful creation of a new "job code" entry. I need to deserialize the response into some classes, but I'm stumped.
For reference, I'm using JSON.NET in .NET 3.5 (running in a SSIS script in SQL Server 2008 R2) to attempt my deserialization. Here's the JSON - which I obviously have no control over as it's coming from someone else's API:
{
"results":{
"jobcodes":{
"1":{
"_status_code":200,
"_status_message":"Created",
"id":444444444,
"assigned_to_all":false,
"billable":true,
"active":true,
"type":"regular",
"name":"1234 Main Street - Jackson"
},
"2":{
"_status_code":200,
"_status_message":"Created",
"id":1234567890,
"assigned_to_all":false,
"billable":true,
"active":true,
"type":"regular",
"name":"4321 Some Other Street - Jackson"
}
}
}
}
In my C# code, I do have a "JobCode" class defined which only partially maps the JSON values to properties - I'm not interested in all of the data that's returned to me:
[JsonObject]
class JobCode
{
[JsonProperty("_status_code")]
public string StatusCode { get; set; }
[JsonProperty("_status_message")]
public string StatusMessage { get; set; }
[JsonProperty("id")]
public string Id {get; set;}
[JsonProperty("name")]
public string Name { get; set; }
//-------------------------------------------------------------------------------
// Empty constructor for JSON serialization support
//-------------------------------------------------------------------------------
public JobCode() { }
}
I'm attempting to deserialize the data via this call:
newResource = JsonConvert.DeserializeObject<JobCode>(jsonResponse);
Where jsonResponse is the code outputted above.
When I execute the code, "newResource" always comes back as null - which is not unexpected because I know that there are actually multiple jobcodes in the data and this code is trying to deserialize it into a single JobCode object. I tried creating a new class called "JobCodes" that looks like this:
class JobCodes
{
[JsonProperty("jobcodes")]
public List<JobCode>_JobCodes { get; set; }
}
And then I tried calling this:
newResource = JsonConvert.DeserializeObject<JobCodes>(jsonResponse);
But the issue persists - my return object is null.
What's throwing me off, I think, is the presence of the "1" and "2" identifiers. I don't know how to account for their presence in my object design and/or usage of the JSON.NET class / property attributes like [JsonObject],[JsonProperty], etc.
When I run the JSON data through JSON2CSharp, it constructs some weird-looking classes, so that hasn't proven too effective. I've validated the JSON with several different validators and it all checks out - I just don't know what I'm missing here.
Ultimately, I'd like to return a List from the JSON data, but I'm stumped on what I need to do to make that happen.
Your problem is twofold:
You don't have a class defined at the root level. The class structure needs to match the entire JSON, you can't just deserialize from the middle.
Whenever you have an object whose keys can change, you need to use a Dictionary<string, T>. A regular class won't work for that; neither will a List<T>.
Make your classes like this:
class RootObject
{
[JsonProperty("results")]
public Results Results { get; set; }
}
class Results
{
[JsonProperty("jobcodes")]
public Dictionary<string, JobCode> JobCodes { get; set; }
}
class JobCode
{
[JsonProperty("_status_code")]
public string StatusCode { get; set; }
[JsonProperty("_status_message")]
public string StatusMessage { get; set; }
[JsonProperty("id")]
public string Id { get; set; }
[JsonProperty("name")]
public string Name { get; set; }
}
Then, deserialize like this:
RootObject obj = JsonConvert.DeserializeObject<RootObject>(json);
Working demo here
Excellent Answers!
For those out there that may need some more help with the JSON Class Configuration, try: http://json2csharp.com/#
An excellent way of Auto Generating the Classes!
Or even easier, in VS, Goto:
Edit -> Paste Special -> Paste as JSON Classes
Because you can't change the scheme of JSON, and you can't set constant No. of properties, I'd suggest you to use JObject
var jobject = JObject.Parse(json);
var results = jobject["results"];
var jobcodes = results["jobcodes"];
var output = jobcodes.Children<JProperty>()
.Select(prop => prop.Value.ToObject<JobCode>())
.ToList();
Warning: code assumes, that JSON is always in proper schema. You should also handle invalid schema (for example where property is not of JobCode scheme).
You can also deserialize your json to an object of your target class, and then read its properties as per normal:
var obj = DeSerializeFromStrToObj<ClassToSerialize>(jsonStr);
Console.WriteLine($"Property: {obj.Property}");
where DeSerializeFromStrToObj is a custom class that makes use of reflection to instantiate an object of a targeted class:
public static T DeSerializeFromStrToObj<T>(string json)
{
try
{
var o = (T)Activator.CreateInstance(typeof(T));
try
{
var jsonDict = JsonSerializer.Deserialize<Dictionary<string, string>>(json);
var props = o.GetType().GetProperties();
if (props == null || props.Length == 0)
{
Debug.WriteLine($"Error: properties from target class '{typeof(T)}' could not be read using reflection");
return default;
}
if (jsonDict.Count != props.Length)
{
Debug.WriteLine($"Error: number of json lines ({jsonDict.Count}) should be the same as number of properties ({props.Length})of our class '{typeof(T)}'");
return default;
}
foreach (var prop in props)
{
if (prop == null)
{
Debug.WriteLine($"Error: there was a prop='null' in our target class '{typeof(T)}'");
return default;
}
if (!jsonDict.ContainsKey(prop.Name))
{
Debug.WriteLine($"Error: jsonStr does not refer to target class '{typeof(T)}'");
return default;
}
var value = jsonDict[prop.Name];
Type t = Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType;
object safeValue = value ?? Convert.ChangeType(value, t);
prop.SetValue(o, safeValue, null); // initialize property
}
return o;
}
catch (Exception e2)
{
Debug.WriteLine(e2.Message);
return o;
}
}
catch (Exception e)
{
Debug.WriteLine(e.Message);
return default;
}
}
A complete working example class can be found in my enhanced answer to a similar question, here
I'm fetching data from website that returns me an object in a string like this:
{
index: 1,
commentNumber: 20,
feedComments: {
3465665: {
text: "I do not agree",
likeRatio: 0
},
6169801: {
text: "Hello",
likeRatio: 12
},
7206201: {
text: "Great job!",
likeRatio: 5
}
}
}
I want to work with this as an object, that's pretty easy to do, I'll just do this:
string objectString = GetData(); // Artificial GetData() method
dynamic data = JObject.Parse(objectString);
And now I can easily get all properties I want from this object using dynamic
The problem is pretty obvious now, I want to get properties, whose name starts with number (the object data structure I fetch is just designed that way). But property/field names you get from object cannot begin with a number.
int commentNumber = data.commentNumber; // Works fine
string commentText = data.feedComments.3465665.text; // Obviously won't compile
Is there any way to do this?
Note that I want to work with data I fetch as it was an object, I know I get get the comment text right from the string that GetData() method returns using some regex or something, but that's something I want to avoid.
You should really be parsing the JSON into concrete C# classes. Dynamic is slow and vulnerable to runtime errors that are hard to detect.
The comments will go into a Dictionary. For example:
public class Root
{
public int Index { get; set; }
public int CommentNumber { get; set; }
public Dictionary<long, FeedComment> FeedComments { get; set; }
}
public class FeedComment
{
public string Text { get; set; }
public int LikeRatio { get; set; }
}
And deserialise like this:
var result = JsonConvert.DeserializeObject<Root>(objectString);
Now you can access the comments very easily:
var commentText = result.FeedComments[3465665].Text
I receive some jsons that are supposed to represent a legal object of some class.
I wish to validate this is indeed so. So I deserialized the strings to see if this succeeds. This is very time consuming as the strings gets very large in some cases and there are many of them. I am therefore looking for a different approach.
I thought of creating a regExp from the class's definition and check that the jsons I receive are compatible. Is there a way to generate a regExp from a C# class?
Any other suggestions will help as well.
Thanks
Use JSON schema validator by newtonsoft , more details here
public class JsonSchemaController : ApiController
{
[HttpPost]
[Route("api/jsonschema/validate")]
public ValidateResponse Valiate(ValidateRequest request)
{
// load schema
JSchema schema = JSchema.Parse(request.Schema);
JToken json = JToken.Parse(request.Json);
// validate json
IList<ValidationError> errors;
bool valid = json.IsValid(schema, out errors);
// return error messages and line info to the browser
return new ValidateResponse
{
Valid = valid,
Errors = errors
};
}
}
public class ValidateRequest
{
public string Json { get; set; }
public string Schema { get; set; }
}
public class ValidateResponse
{
public bool Valid { get; set; }
public IList<ValidationError> Errors { get; set; }
}
I'm getting empty lists when I deserialize one of my List that has been concerted to XML.
I start out with my object GJurisdictions and serialize it to XML
<open511 xml:lang="en" xml:base="http://api.open511.info/" version="v0">
<jurisdictions>
<jurisdiction>
<id>my.id</id>
<languages>
<language>en</language>
</languages>
</jurisdiction>
</jurisdictions>
</open511>
This is exactly what I want but when I try to read it back in Languages is empty.
public class Jurisdiction
{
[XmlElement("id")]
[JsonProperty("id")]
public string Id { get; set; }
[XmlArray("languages")]
[XmlArrayItem("language")]
[JsonProperty("languages")]
public List<String> Languages { get; set; }
}
[XmlRoot("open511")]
public class JurisdictionsBase : Open511Base
{
private List<Jurisdiction> _jurisdictions;
[XmlArray("jurisdictions")]
[XmlArrayItem("jurisdiction")]
[JsonProperty("jurisdiction")]
public List<Jurisdiction> Jurisdictions
{
get { return _jurisdictions ?? (_jurisdictions = new List<Jurisdiction>()); }
set { _jurisdictions = value; }
}
}
The list of jurisdictions serializes perfectly and all the other properties (I edited for clarity) serialize perfectly but the language list is always empty, why?
Specification: http://open511.org/jurisdiction.html
Full Code: https://github.com/doublej42/Open511DotNet/blob/master/Open511DotNet/Jurisdiction.cs
So I didn't give enough information without reading the full source code. My problem was that somewhere else in my project I used some sample code from http://msdn.microsoft.com/en-us/library/system.xml.serialization.ixmlserializable.readxml(v=vs.110).aspx
public void ReadXml (XmlReader reader)
{
personName = reader.ReadString();
}
Do not use the above code
it doesn't move the reader ahead correctly.
As mentioned here http://msdn.microsoft.com/query/dev12.query?appId=Dev12IDEF1&l=EN-US&k=k(System.Xml.XmlReader.ReadString);k(TargetFrameworkMoniker-.NETFramework,Version%3Dv4.5.1);k(DevLang-csharp)&rd=true
public void ReadXml(System.Xml.XmlReader reader)
{
_unit = reader.ReadElementContentAsString();
}
I've had a look at a few threads but what I'm aiming for I can't seem to find.
I have the following JSON strings returned:
On success:
{"success":{"username":"key"}}
On Error:
{"error":{"type":101,"address":"/","description":"link button not pressed"}}
I need to be able to de-serialize these into a class and determine whether I've got an error or a success message to carry on doing it. Any ideas on how to achieve this?
thanks,
Adam
No need to declare a lot of tiny classes. dynamic keyword can help here.
dynamic jObj = JObject.Parse(json);
if (jObj.error!= null)
{
string error = jObj.error.description.ToString();
}
else
{
string key = jObj.success.username.ToString();
}
One option is to use http://nuget.org/packages/newtonsoft.json - you can either create your own custom class to deserialize into or use dynamic as the target type.
var result = JsonConvert.DeserializeObject<Result>(jsonString);
class Result
{
public SuccessResult success { get; set; }
public ErrorResult error { get; set; }
}
class SuccessResult
{
public string username { get; set; }
}
class ErrorResult
{
public int type { get; set; }
public string address { get; set; }
public string description { get; set; }
}
If you need just to check for success, it is possible to just check result.StartsWith("{\"success\":") to avoid unnecessary parsing. But this should only be done if you have guarantee that the JSON string will always be exactly like this (no extra whitespaces etc.) - so it is usually only appropriate if you own the JSON generation yourself.
This answer covers most options, including rolling your own parser and using JSON.Net:
Parse JSON in C#
You could also just write a regex if the format is going to be that simple...