Detect end of json object using Newtonsoft.Json - c#

I have a string that starts with a JSON object but after the end of which the string goes on (something like {"a":"fdfsd","b":5}ghresd). The text afterward can contain any character and the JSON can be anything allowed for a JSON.
I would like to deserialize the JSON object and know where it ends because I want to process the rest of the string afterward, how do I do that, preferably using Newtonsoft.Json?

You could make use of the SupportMultipleContent property, for example:
var json = "{\"a\":\"fdfsd\",\"b\":5}ghresd";
var reader = new JsonTextReader(new StringReader(json));
reader.SupportMultipleContent = true;
//Read the first JSON fragment
reader.Read();
var serializer = new JsonSerializer();
var result = serializer.Deserialize(reader);
//Or if you have a class to deserialise into:
//var result = serializer.Deserialize<YourClassHere>(reader);
//Line position is where the reader got up to in the JSON string
var extraData = json.Substring(reader.LinePosition);

This piece of code might not work as expected if your json has multiple lines:
var extraData = json.Substring(reader.LinePosition);
You might need to consider adding additional check:
if(reader.LineNumber != 1)
throw new NotSupportedException("Multiline JSON objects are not supported.");
Or you can take that value from private field using Reflection:
var charPosition = (int)reader.GetType().GetField("_charPos", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(reader);
JsonTextReader source code

Related

How to use Json.Net to deserialize json that starts with a property name of a number?

I am trying to deserialize some JSON data from an API endpoint, and the data is enclosed in a {8: myData}. I cannot figure out how to deserialize it with the first property being named a number.
Example JSON:
{
8:
[
data,
data2,
data3,
data4
]
}
My deserializer line fails since the first property name of the JSON data is an 8:
IEnumerable<ApiCombatOverallRank> result = JsonConvert.DeserializeObject<IEnumerable<ApiCombatOverallRank>>(resultsString);
I can create an anonymous type like this:
var anonType = new { data = new List<ApiCombatOverallRank>() };
IEnumerable<ApiCombatOverallRank> result = JsonConvert.DeserializeAnonymousType(resultsString, anonType).data;
However, it will not deserialize as the property name in the JSON is 8 not data. C# will not allow me to create an anonymous object like:
var anonType = new { 8 = new List<ApiCombatOverallRank>() };
Similarly, I am unable to add an annotation to an anonomyous object like:
var anonType = new {[JsonProperty(PropertyName = "8")] data = new List<ApiCombatOverallRank>() };
How can I deserialize this JSON and get past the first JSON object property of 8?
Your json is parsebar as (after i made strings from your "data's" ):
var result = JsonConvert
.DeserializeObject<Dictionary<int, IEnumerable<string>>>(resultsString);
so i think, your real json you could parse as :
var result = JsonConvert
.DeserializeObject<Dictionary<int, IEnumerable<ApiCombatOverallRank>>>(resultsString);
and your first kson object your could access as:
result[8].First();

How to modify a deserialized object

I have a JSON string as follows
string str = "{"Id":["1799"],"Type":1,"Date":null,"Group":null,"Ids":1799}";
I want to covert it to the following format
{"Id":1799,"Type":1,"Date":null,"Group":null }
In short I want to remove the "Ids" and convert "Id" value to string.
For this I tried deserializing this string as follows-
object yourOjbect = new JavaScriptSerializer().DeserializeObject(str);
But here I am stuck. How Can I remove/change a value from this object.
I tried converting this object to array and list but could not find remove/modify option in it.
Maybe you can use the JSON framework for .NET from http://www.newtonsoft.com/json (also available as a nuget package)
Then you can use the following to Deserialize into your object
string str = "{"Id":["1799"],"Type":1,"Date":null,"Group":null,"Ids":1799}";
MyObject myObj = JsonConvert.DeserializeObject<MyObject>(json);
Then maybe create a different object for your output, and have a constructor that will accept the original object as input, and then serialise it to Json. The constructor must then do any internal conversions/changes that you require.
OtherObject other = new OtherObject(myObj); //Create new object from original.
string json = JsonConvert.SerializeObject(other);
Expando Object.
string str = "{"Id":["1799"],"Type":1,"Date":null,"Group":null,"Ids":1799}";
Initially, deserialize the json using NewtonJson lib
dynamic parsedJson = JsonConvert.DeserializeObject<dynamic>(str);
Dynamic newStr = new ExpandoObject();
newStr.Id = parsedJson.Id.ToString();
newStr.Type = parsedJson.Type;
...
then serilize the newStr:
str newJson = JsonConvert.SerializeObject(newStr);
Output :
{"Id":1799,"Type":1,"Date":null,"Group":null }

Parsing through MSDN text?

Trying to figure out how I can parse through this information, it looks like JSON but I can't tell if it is or not (no .json at the end). I've been treating it as JSON and have been trying to parse through it
string url = "https://services.social.microsoft.com/searchapi/en-US/Msdn?query=" + query + "&maxnumberedpages=5&encoderesults=1&highlightqueryterms=1";
HtmlDocument doc = new HtmlDocument();
HttpWebRequest request = (HttpWebRequest) WebRequest.Create(url);
var response = (HttpWebResponse) request.GetResponse();
var reader = new StreamReader(response.GetResponseStream());
var objText = reader.ReadToEnd();
List<string[]> data = JsonConvert.DeserializeObject<List<string[]>>(objText);
foreach (string[] test in data)
{
foreach (string sub_text in test)
{
Console.WriteLine(sub_text);
}
}
But it gives me an error that it's not a JSON array, so I'm beginning to think it's not JSON.
I'm just looking for a push in the right direction, here's a sample of the data I would get:
https://services.social.microsoft.com/searchapi/en-US/Msdn?query=dynamic%20arrays&maxnumberedpages=5&encoderesults=1&highlightqueryterms=1
and I would want to grab the all arrays that the have 'id' at the start. How can I go about this?
It is valid Json.
Problem is that you are trying to Deserialize into Array which is not correct.
var data = JsonConvert.DeserializeObject(objText);
Looks like the issue is this line
List<string[]> data = JsonConvert.DeserializeObject<List<string[]>>(objText);
What you are trying to deserialize is not a string array, it's an object. To correctly deserialize it, you would need to create a set of classes that model the data structure. You may also explore using a Jobject in the JSON.net library as an alternative.

JavaScriptSerializer doesn't serialize DynamicJsonObject properly

I have a DynamicJsonObject like:
var obj = new DynamicJsonObject();
obj.Field1 = "field1";
obj.Field2 = "field2";
I need the obj's json string. I tried using JavaScriptSerializer:
var json = JavaScriptSerializer.Serialize(obj);
But the result is always json == '{}'
Is there a workaround for this? preferably not using third party libraries
You can add custom converter to JavaScriptSerializer. In System.Web.Helpers one already exists but is internal - you can use the following code to register it:
var type = Type.GetType("System.Web.Helpers.DynamicJavaScriptConverter, System.Web.Helpers");
var converter = (JavaScriptConverter)Activator.CreateInstance(type);
JavaScriptSerializer serializer = new JavaScriptSerializer();
serializer.RegisterConverters(new[] { converter });
var json = serializer.Serialize(obj);
or copy code from here
Thanks for your answers, but I've found a simple way to do this by using System.Web.Helpers.Json.
So, my code looks like this:
string json = Json.Encode(obj);
I cannot use an anonymous object, because I don't create obj, it is provided in the DynamicJsonObject 'format' already.

Convert JSON response stream to string

I am trying to do a POST and then read the JSON response into a string.
I believe my issue is that I need to pass my own object into DataContractJsonSerializer but I'm wondering if there is some way to just get the response into an associative array or some sort of key/value format.
My JSON is formatted like: {"license":"AAAA-AAAA-AAAA-AAAA"} and my code is as follows:
using (Stream response = HttpCommands.GetResponseStream(URL, FormatRegistrationPost(name, email)))
{
string output = new StreamReader(response).ReadToEnd();
response.Close();
DataContractJsonSerializer json = new DataContractJsonSerializer(typeof(string));
MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(output));
string results = json.ReadObject(ms) as string;
licenseKey = (string) results.GetType().GetProperty("license").GetValue(results, null);
}
I'd strongly recommend looking into Newtonsoft.Json:
http://james.newtonking.com/pages/json-net.aspx
NuGet: https://www.nuget.org/packages/newtonsoft.json/
After adding the reference to your project, you just include the following using at the top of your file:
using Newtonsoft.Json.Linq;
And then within your method you can use:
var request= (HttpWebRequest)WebRequest.Create("www.example.com/ex.json");
var response = (HttpWebResponse)request.GetResponse();
var rawJson = new StreamReader(response.GetResponseStream()).ReadToEnd();
var json = JObject.Parse(rawJson); //Turns your raw string into a key value lookup
string license_value = json["license"].ToObject<string>();
you can do something like this using dictionary
Dictionary<string, string> values =
JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
or something like this if you already know your object
var yourobject = JsonConvert.DeserializeObject<YourObject>(json);
with this tool
http://james.newtonking.com/projects/json/help/
reference here
Using JsonConvert.DeserializeObject to deserialize Json to a C# POCO class

Categories

Resources