C# How to extract certain info long string - c#

Okay I have been trying all day long with Regex and some other methods with no luck, here's what i'm trying to do i will try to make it as simple as I can, this an API and I am getting JSON response from my site like this:
{"user_id":1,"username":"xxx","email":"xxx#xxx.com","gender":"male","title":"","language_id":1,"timezone":"Africa\/Nairobi","visible":1,"activity_visible":1,"user_group_id":3,"secondary_group_ids":"2,4,6,8,11,12,13,16,19,20","message_count":235,"conversations_unread":0,"register_date":1424485355,"last_activity":1436186781,"trophy_points":43,"alerts_unread":2,"avatar_date":1435657653,"avatar_width":180,"avatar_height":224,"gravatar":"","user_state":"valid","is_moderator":0,"is_admin":1,"is_banned":0,"like_count":127,"warning_points":0,"is_staff":1,"advapps":"a:1:{i:0;a:2:{s:5:\"posid\";i:1;s:5:\"count\";i:5;}}","brms_statistic_perferences":"a:1:{i:1;s:1:\"0\";}","bratr_ratings":38,"tc_cui_icon":"","tc_cui_color":"#000000","breta_user_level":5,"breta_curent_level":34,"breta_next_level":45,"credits":"13402154377.480000","brc_points":"999999.000000","br_profile_image":"","br_cropy":"0.00",""}}
What i want to extract is user_group_id and secondary_group_ids then parse the numbers and add them to array then compare them with the given number, i want to check if the member is in that group number (secondary or primary does not matter).
How can i do that with the best and easiest way?

First, deserialize your JSON string to a .NET Dictionary. For example, with JSON.NET:
string json = #"[
{
'Name': 'Product 1',
'ExpiryDate': '2000-12-29T00:00Z',
'Price': 99.95,
'Sizes': null
},
{
'Name': 'Product 2',
'ExpiryDate': '2009-07-31T00:00Z',
'Price': 12.50,
'Sizes': null
}
]";
List<Product> products = JsonConvert.DeserializeObject<List<Product>>(json);
Console.WriteLine(products.Count);
// 2
Product p1 = products[0];
Console.WriteLine(p1.Name);
// Product 1
Then you can use basic LINQ queries against the Dictionary.

I suggest you use DataContractJsonSerializer to deserialize the Json string into a C# object.

Related

How to merge two json documents in json.net?

I'm not sure of the correct terminology as not overly knowledgeable about json. I have an existing json string/object of the following fixed format (i.e. all items are at the root level and of straightforward key/value pairs, although the number of items can vary):
{
"product_id": "1777",
"license_key": "ECHOES-SILENCE-PATIENCE-AND-GRACE",
"valid_for": "365",
"status": "active",
"times_activated_max": 1
}
I need a way to add a json string of varying schema/format that is passed into a method. This object can be of any json format. It's to be added to the root. For example adding this:
{
"name":"John",
"age":30,
"cars":["Ford", "BMW", "Fiat"]
}
..will become this:
{
"product_id": "1777",
"license_key": "ECHOES-SILENCE-PATIENCE-AND-GRACE",
"valid_for": "365",
"status": "active",
"times_activated_max": 1
"name":"John",
"age":30,
"cars":["Ford", "BMW", "Fiat"]
}
I have Newtonsoft.Json at my disposal for this.
I did read this but couldn't map it to my problem.
Hope someone can help
The JSON.NET documentation has an article just for that: Merging JSON. You can use JObject.Merge to merge two different objects into one:
JObject o1 = JObject.Parse(#"{
'FirstName': 'John',
'LastName': 'Smith',
'Enabled': false,
'Roles': [ 'User' ]
}");
JObject o2 = JObject.Parse(#"{
'Enabled': true,
'Roles': [ 'User', 'Admin' ]
}");
o1.Merge(o2, new JsonMergeSettings
{
// union array values together to avoid duplicates
MergeArrayHandling = MergeArrayHandling.Union
});
What you posted is two objects. A JSON document may be text, but what it contains are arrays and objects. "Merging" means finding a way to combine those objects/arrays and produce a new array or object.
Merge is defined by JContainer, the parent of both JObject and JArray. This means you can use Merge to merge both arrays and objects.
Another option with arrays is to use Enumerable.Union to combine the contents of both arrays, and create a new one :
var array1= JArray.Parse("[1,2,3]");
var array2= JArray.Parse("[3,4,5, \"a\"]");
var array3=new JArray(array1.Union(array2));
This returns [1,2,3,4,5,"a"]
Json.net uses the JObject type to represent arbitrary JSON objects. This has a handy Merge method for combining two JObjects.
Simply:
string s1 = #"
{
""product_id"": ""1777"",
""license_key"": ""ECHOES-SILENCE-PATIENCE-AND-GRACE"",
""valid_for"": ""365"",
""status"": ""active"",
""times_activated_max"": 1
}";
string s2 = #"
{
""name"":""John"",
""age"":30,
""cars"":[""Ford"", ""BMW"", ""Fiat""]
}";
JObject o1 = JObject.Parse(s1);
JObject o2 = JObject.Parse(s2);
o1.Merge(o2);
Console.WriteLine(o1);
See it here

LINQ-TO-JSON cannot get value in array

I am trying to get values with LINQ-TO-JSON in this JSON-TREE, So far it looks good until i've approached this categories element.
I want to get the value "Teknik" from this value and this is what i've tried to far without success.
Name = json["items"][i]["categories"].Children().Value<string>() ?? "Not assigned"
Name = json["items"][i]["categories"][0].Value<string>() ?? "Not assigned"
Name = json["items"][i]["categories"].First.Value<string>()
But none of these results works for me. Please help!
You didn't post the actual JSON string and the "tree" doesn't help. The JSON string in Querying JSON with LINQ could be represented with a similar tree, so I'll assume that's your source data:
string json = #"{
'channel': {
'title': 'James Newton-King',
'link': 'http://james.newtonking.com',
'description': 'James Newton-King\'s blog.',
'item': [
{
'title': 'Json.NET 1.3 + New license + Now on CodePlex',
'description': 'Annoucing the release of Json.NET 1.3, the MIT license and the source on CodePlex',
'link': 'http://james.newtonking.com/projects/json-net.aspx',
'categories': [
'Json.NET',
'CodePlex'
]
},
{
'title': 'LINQ to JSON beta',
'description': 'Annoucing LINQ to JSON',
'link': 'http://james.newtonking.com/projects/json-net.aspx',
'categories': [
'Json.NET',
'LINQ'
]
}
]
}
}";
JObject rss = JObject.Parse(json);
The example shows two ways to access values, through indexers or LINQ queries.
Using indexers, you'd only need [0] to access the first category of an item, eg:
rss["items"][i]["categories"][0];
That returns a JValue object as a JObject. You can cast it directly to string to get its value, eg:
(string)rss["items"][i]["categories"][0]
Or to a JValue, if you want to handle it as a JSON object and read the Value property, eg:
(rss["items"][i]["categories"][0] as JValue).Value;
A LINQ query wouldn't need indexers. If you wanted to retrieve the Category names you could write :
var query= from item in rss["channel"]["item"]
from category in item["categories"]
select new {Name=(string)category};
Or
var query = from category in rss["channel"]["item"].SelectMany(item=>item["categories"])
select new {Name=(string)category};
Or
var query = rss["channel"]["item"].SelectMany(item=>item["categories"])
.Select(category=>new {Name=(string)category});

Youtube Data v3 Api, Get Request sort

Hey everyone i'm trying to use the v3 Data Youtube API, already have the Request itself and the response looks like this
{
"items": [
{
"snippet": {
"publishedAt": "2016-12-07T16:04:40.472Z",
"displayMessage": "a"
}
}
]
}
The Problem is that i only want the last Comment and not the whole 200(cant be set lower) my first Idea was to Save the whole Response and Compare it to the next one so i know whats new, but that wont really work out
Ok, so from the comments, I gather you are talking about the Live Streaming API.
What you get back are messages, not comments. And yes, as the doc says, "Acceptable values are 200 to 2000, inclusive. The default value is 500." So, you could get the whole 200, and then sort on the timestamp to get the latest message.
How to do that?
As you are doing this in C#, once you have the json string, you need to use some library such as Json.NET. Once you add a NuGet package reference to this, you will need
using Newtonsoft.Json.Linq;
and say your json string is
var json = #"{
""items"": [
{
""snippet"": {
""publishedAt"": ""2016-12-07T16:04:40.472Z"",
""displayMessage"": ""a""
}
}
,
{
""snippet"": {
""publishedAt"": ""2016-12-12T16:04:40.472Z"",
""displayMessage"": ""b""
}
}
]
}";
Then, as described in this documentation, use JObject.Parse to use LINQ to JSON.
var parsedJson = JObject.Parse(json);
JArray items = parsedJson.SelectToken("items") as JArray;
var sortedItems = items.OrderByDescending(item => item["snippet"]["publishedAt"]);
// sortedItems.First() will give you the item with the newest timestamp
Have put all of this at https://dotnetfiddle.net/ubQAZV.
Alternately, you can use JsonConvert if you prefer to deserialize to strongly-typed code.
More about it here.

Can I use .NET Newtonsoft JSON package (with or without Linq) to deserialize this oddly formatted JSON response?

I receive this JSON response (but I'm not even sure if this is valid JSON. is it?):
"{\"fields\":\"Name,ParentName,Description,StartDate,EndDate,StartMinute,EndMinute\",\"pos\":0,\"start\":0,\"totalRecords\":1001881,\"data\":[[null,\"AAEC 3400 76142\",null,\"2014-05-15T00:00:00\",\"2014-05-15T00:00:00\",840,1050],[null,\"AAEC 3400 76142\",null,\"2014-05-28T00:00:00\",\"2014-05-28T00:00:00\",840,1050],[null,\"ACCT 5400 25030\",null,\"2014-01-08T00:00:00\",\"2014-01-08T00:00:00\",1215,1290],[null,\"ACCT 5400 25030\",null,\"2014-02-19T00:00:00\",\"2014-02-19T00:00:00\",1215,1290]]}"
Is it possible to deserialize this response and access particular values using Newtonsoft JSON package, with or without the LINQ namespace? Can I access specific values from the "data" key?
Currently, my approach is to manipulate this JSON response into regular JSON, so instead of just having a "fields" key and a "data" key followed by lists of values, I end up deserializing normal JSON key/value pairs (like "Name":"null", "ParentName":"AAEC 3400 76142\", . . . ). Then I can access each object in the list's values by key.
But is it possible to access specific values keeping the response the way it came, without parsing/manipulating it, using Newtonsoft JSON package with/without methods in LINQ namespace?
This is how I'm deserializing the json string that I parse/manipulated manually into normal JSON:
var myList = JsonConvert.DeserializeObject<List<MyClass>>(json);
Then I can access values by key off of specific objects in the response by index:
String name = myList[0].Name;
But can I access the value of myList[0].Name without reformatting the JSON response into typical key:value pairs? Does Newtonsoft provide a way to access the value I want from the response the way it came?
Looks like that JSON has been double-serialized. I.e. some class was serialized as a JSON string, then that string was serialized as JSON again, causing JSON control characters including {,} and " characters to be escaped.
This is almost certainly a bug on the server side, you should try to get it fixed there. But if you cannot (for political reasons, say), you can check for this and work around it on the client side:
var token = JToken.Parse(json);
if (token.Type == JTokenType.String)
token = JToken.Parse((string)token);
var myList = token.ToObject<List<MyClass>>();
Update: your root JSON container is an object, not an array, so ToObject<List<MyClass>> won't work. The unwrapped JSON looks like:
{
"fields": "Name,ParentName,Description,StartDate,EndDate,StartMinute,EndMinute",
"pos": 0,
"start": 0,
"totalRecords": 1001881,
"data": [
[
null,
"AAEC 3400 76142",
null,
"2014-05-15T00:00:00",
"2014-05-15T00:00:00",
840,
1050
],
// More of the same
]
}
If you wanted to reformat that into a more traditional array of JSON objects, you could restructure your root JToken like so:
var token = JToken.Parse(json);
if (token.Type == JTokenType.String)
token = JToken.Parse((string)token);
var fields = (string)token.SelectToken("fields");
var fieldList = fields.Split(',');
var root = new JArray();
root.Add(token.SelectTokens("data[*]").OfType<JArray>().Select(a => new JObject(a.Zip(fieldList, (t, s) => new JProperty(s, t)))));
Debug.WriteLine(root);
With the result:
[
{
"Name": null,
"ParentName": "AAEC 3400 76142",
"Description": null,
"StartDate": "2014-05-15T00:00:00",
"EndDate": "2014-05-15T00:00:00",
"StartMinute": 840,
"EndMinute": 1050
},
// More of the same
]
Yes. It is straightforward and simple to deserialize a JSON response formatted in this way using the Newtonsoft JSON package with LINQ namespace. You don't have to manipulate the response string by hand. Set the JSON response string to a string object named "response", use JObject.Parse() to create a dynamic object "jobject", then you can access the "data" JSON key and set it to a JArray object. Then you can loop through each JToken in "jArray". Finally, get the values by their index in the JArray:
dynamic jobject = JObject.Parse(response);
JArray jArray = jobject.data;
foreach (JToken appointment in jArray)
{
parentName = appointment[1];
startMinute = appointment[5];
. . .
}

How to parse a JSON array in C#?

Using the MongoDB C# driver how can I parse a JSON array (string) into BsonDocument[]?
We would like to store our mongo aggregation pipelines in separate JSON documents so need a way to parse them.
Not a bad idea if that suits your purposes. Yes the C# driver already supports BSON serialization from a JSON string source:
string json = '[
{ "$match: { "foo": "bar" } },
{ "$group": {
"_id": null,
"count": { "$sum": 1 }
}}
]';
BsonDocument pipeline =
MongoDB.Bson.Serialization.BsonSerializer.Deserialize<BsonArray>(json);
So you can pull in your aggregation pipeline strings formatted as JSON and use them or manipulate them as BSON documents.
The accepted answer's result is a BsonArray, if you need a BsonDocument[] you'll do something like
BsonSerializer.Deserialize<BsonArray>(yourJsonString).Select(p => p.AsBsonDocument)
and if you need it as a List<BsonDocument>
BsonSerializer.Deserialize<BsonArray>(yourJsonString).Select(p => p.AsBsonDocument).ToList<BsonDocument>()

Categories