Best ways to split a string with matching curly braces - c#

I'm working in C# right now and I'm using JSON.Net to parse json strings to well, C# objects. Part of my problem is that I'm getting some strings like this:
{"name": "John"}{"name": "Joe"}
When I try to deserialize with JsonConvert.DeserializeObject<>, it throws an exception.
I'm wondering what would be the best way to split of this bigger string into smaller json strings.
I was thinking about going through the string and matching curly braces of "level 0". Does this seem like a good idea? Or is there some better method to do this?

You can use a JsonTextReader with the SupportMultipleContent flag set to true to read this non-standard JSON. Assuming you have a class Person that looks like this:
class Person
{
public string Name { get; set; }
}
You can deserialize the JSON objects like this:
string json = #"{""name"": ""John""}{""name"": ""Joe""}";
using (StringReader sr = new StringReader(json))
using (JsonTextReader reader = new JsonTextReader(sr))
{
reader.SupportMultipleContent = true;
var serializer = new JsonSerializer();
while (reader.Read())
{
if (reader.TokenType == JsonToken.StartObject)
{
Person p = serializer.Deserialize<Person>(reader);
Console.WriteLine(p.Name);
}
}
}
Fiddle: https://dotnetfiddle.net/1lTU2v

I found the best way is to convert your string to an array structure:
string json = "{\"name\": \"John\"}{\"name\": \"Joe\"}";
json = json.Insert(json.Length, "]").Insert(0, "[").Replace("}{", "},{");
// json now is [{"name": "John"},{"name": "Joe"}]
List<Person> result = Newtonsoft.Json.JsonConvert.DeserializeObject<List<Person>>(json);
Assuming your class name is Person :
public class Person
{
public string Name { set; get; }
}

Related

Remove Quotes From Json Property Key In C# [duplicate]

I'm trying to get Json.Net to serialise a property name without quote marks, and finding it difficult to locate documentation on Google. How can I do this?
It's in a very small part of a large Json render, so I'd prefer to either add a property attribute, or override the serialising method on the class.
Currently, the it renders like this:
"event_modal":
{
"href":"file.html",
"type":"full"
}
And I'm hoping to get it to render like: (href and type are without quotes)
"event_modal":
{
href:"file.html",
type:"full"
}
From the class:
public class ModalOptions
{
public object href { get; set; }
public object type { get; set; }
}
It's possible, but I advise against it as it would produce invalid JSON as Marcelo and Marc have pointed out in their comments.
Using the Json.NET library you can achieve this as follows:
[JsonObject(MemberSerialization.OptIn)]
public class ModalOptions
{
[JsonProperty]
public object href { get; set; }
[JsonProperty]
public object type { get; set; }
}
When serializing the object use the JsonSerializer type instead of the static JsonConvert type.
For example:
var options = new ModalOptions { href = "file.html", type = "full" };
var serializer = new JsonSerializer();
var stringWriter = new StringWriter();
using (var writer = new JsonTextWriter(stringWriter))
{
writer.QuoteName = false;
serializer.Serialize(writer, options);
}
var json = stringWriter.ToString();
This will produce:
{href:"file.html",type:"full"}
If you set the QuoteName property of the JsonTextWriter instance to false the object names will no longer be quoted.
You can also try a regex replace, with a substitution, which could handle any serialized object, and replace the quotes for you.
For Example:
var options = new ModalOptions { href = "file.html", type = "full" };
string jsonText = JsonConvert.SerializeObject(options);
string regexPattern = "\"([^\"]+)\":"; // the "propertyName": pattern
Console.WriteLine(Regex.Replace(jsonText, regexPattern, "$1:"));
This would produce:
{href:"file.html",type:"full"}
I built a working web example here.
Explanation of regex substitutions are here.

How to get rid of quotes in JSON file property name using NewtonSoft JSON.Net Serialize()? [duplicate]

I'm trying to get Json.Net to serialise a property name without quote marks, and finding it difficult to locate documentation on Google. How can I do this?
It's in a very small part of a large Json render, so I'd prefer to either add a property attribute, or override the serialising method on the class.
Currently, the it renders like this:
"event_modal":
{
"href":"file.html",
"type":"full"
}
And I'm hoping to get it to render like: (href and type are without quotes)
"event_modal":
{
href:"file.html",
type:"full"
}
From the class:
public class ModalOptions
{
public object href { get; set; }
public object type { get; set; }
}
It's possible, but I advise against it as it would produce invalid JSON as Marcelo and Marc have pointed out in their comments.
Using the Json.NET library you can achieve this as follows:
[JsonObject(MemberSerialization.OptIn)]
public class ModalOptions
{
[JsonProperty]
public object href { get; set; }
[JsonProperty]
public object type { get; set; }
}
When serializing the object use the JsonSerializer type instead of the static JsonConvert type.
For example:
var options = new ModalOptions { href = "file.html", type = "full" };
var serializer = new JsonSerializer();
var stringWriter = new StringWriter();
using (var writer = new JsonTextWriter(stringWriter))
{
writer.QuoteName = false;
serializer.Serialize(writer, options);
}
var json = stringWriter.ToString();
This will produce:
{href:"file.html",type:"full"}
If you set the QuoteName property of the JsonTextWriter instance to false the object names will no longer be quoted.
You can also try a regex replace, with a substitution, which could handle any serialized object, and replace the quotes for you.
For Example:
var options = new ModalOptions { href = "file.html", type = "full" };
string jsonText = JsonConvert.SerializeObject(options);
string regexPattern = "\"([^\"]+)\":"; // the "propertyName": pattern
Console.WriteLine(Regex.Replace(jsonText, regexPattern, "$1:"));
This would produce:
{href:"file.html",type:"full"}
I built a working web example here.
Explanation of regex substitutions are here.

How to map json and skip parent property?

I have this json string, which contains two elements each with a Number and a Status:
var jsonString = "{\"Errors\":[{\"Number\":9,\"Status\":\"BadRequest\"}, {\"Number\":3,\"Status\":\"BadConnection\"}]}";
As you see it has a parent property called Errors.
I have prepared this model:
public class ExceptionStructure
{
public int Number { get; set; }
public string Status { get; set; }
}
Using NewtonSoft.Json I would like to deserialize the json string into an array of ExceptionStructure objects, without also having to create a model for the parent property (as I don't really need it).
Can I do this (perhaps with some json attribute on the model class)?
I was hoping to do something like this to deserialize:
var exceptionArr = JsonConvert.DeserializeObject<ExceptionStructure>(jsonString);
JSON.NET allows you to deserialize parts of a json file. You can do this by first deserialzing the json string to a JObject, extract the relevant parts, and then deserialize those to your actual object.
JObject errors = JObject.Parse(jsonString);
IList<JToken> results = errors["Errors"].Children().ToList();
IList<ExceptionStructure> exceptions = new List<ExceptionStructure>();
foreach (JToken result in results)
{
ExceptionStructure exception= result.ToObject<ExceptionStructure>();
exceptions.Add(exception);
}
Honestly though, in your case it might be easier to just build a Errors parent class
More information can be found at http://www.newtonsoft.com/json/help/html/SerializingJSONFragments.htm
this is may be helpful you.
string s = "{\"Errors\":[{\"Number\":9,\"Status\":\"BadRequest\"}, {\"Number\":3,\"Status\":\"BadConnection\"}]}";
var jobj = JObject.Parse(s);
List<ExceptionStructure> list = jobj["Errors"].ToObject<List<ExceptionStructure>>();
OR:
string s = "{\"Errors\":[{\"Number\":9,\"Status\":\"BadRequest\"}, {\"Number\":3,\"Status\":\"BadConnection\"}]}";
List<ExceptionStructure> list = JObject.Parse(s)
.SelectToken("Errors")
.ToObject<List<ExceptionStructure>>();

How to parse non-array JSON?

I am trying to read json from a local .json file and parse the contents using StreamReader and Json.NET. Json & my code:
contents of .json file: {"rate":50,"information":{"height":70,"ssn":43,"name":"andrew"}}
using (var sr = new StreamReader(pathToJsonFile))
{
dynamic jsonArray = JsonConvert.DeserializeObject(sr.ReadToEnd());
foreach(var item in jsonArray)
{
Console.WriteLine(item.rate);
Console.WriteLine(item.ssn);
}
}
This gives me an error on the line foreach(var item in array): Object reference not set to an instance of an object. I am guessing this is because my json is not actually an array but that is how I am trying to parse it. How can I parse this json in order to pull out fields such as rate or ssn?
NB - please do not flag this question as a duplicate of Read and parse a Json File in C#, as that is where I got my original code from.
EDIT: As has been pointed out in other answers, jsonArray is null. That explains my error but still does not answer my question. How else can I parse this json in order to extract the desired fields?
A couple things:
If you want to manually parse out the values, you should try using JObject rather than JsonConvert.DeserializeObject. The following code should work:
dynamic jsonObject = JObject.Parse("{'rate':50,'information':{'height':70,'ssn':43,'name':'andrew'}}");
Console.WriteLine(jsonObject["rate"]);
Console.WriteLine(jsonObject["information"]["ssn"]);
However, if you know how the json is structured, you should create a .net class like:
public class Person
{
public int rate {get;set;}
public Information information {get;set;}
}
public class Information
{
public int height {get;set;}
public int ssn {get;set;}
public string name {get;set;}
}
and then use:
var person = JsonConvert.DeserializeObject<Person>(thestringtodeserialize);
That way you can have a strongly typed object.
In any case, I would check for null (DeserializeObject can obviously return null):
using (var sr = new StreamReader(pathToJsonFile))
{
dynamic jsonArray = JsonConvert.DeserializeObject(sr.ReadToEnd());
if(jsonArray != null) //new check here
{
foreach(var item in jsonArray)
{
Console.WriteLine(item.rate);
Console.WriteLine(item.ssn);
}
}
I am guessing this is because my json is not actually an array
True, the returned object is dynamic, so make use of dynamic:
var json = "{\"rate\":50,\"information\":{\"height\":70,\"ssn\":43,\"name\":\"andrew\"}}";
dynamic obj = JsonConvert.DeserializeObject(json);
Console.WriteLine("rate: {0}. ssn: {1}", obj.rate, obj.information.ssn);
See live sample here: https://dotnetfiddle.net/nQYuyX
Are you sure it's an array?
If that's the format the you expect from Json, maybe you should consider defining a class.
For example:
class SomeJsonObject
{
public int rate {get;set;}
[JsonProperty("information")] //if you want to name your property something else
public InformationObject Information {get;set;}
}
class InformationObject
{
[JsonProperty("height", NullValueHandling = NullValueHandling.Ignore)] //some other things you can do with Json
public int Height {get;set;}
public int ssn {get;set;}
public string name {get;set;}
}
This way you can just deserialize it to an object:
SomeJsonObject jsonArray = JsonConvert.DeserializeObject<SomeJsonObject>(sr.ReadToEnd());
I think your question is similar to this Deserialize JSON with C# . you can use JavaScriptSerializer
I don't get a null reference (with Json.net 6.0.3) but your code has one obvious bug:
static void Main(string[] args)
{
string s = "{'rate':50,'information':{'height':70,'ssn':43,'name':'andrew'}}".Replace('\'', '\"');
var obj = JsonConvert.DeserializeObject(s);
dynamic jsonArray = obj;
foreach (var item in jsonArray)
{
Console.WriteLine(item.rate);
Console.WriteLine(item.ssn);
}
}
The bug is Console.WriteLine(item.rate) will throw.
Your 'array' jsonArray is not actually an array, it is a dictionary!
Therefore, item=the first Key-Value-pair in the dictionary, = {"rate":50}.
You can prevent the code from throwing by getting rid of your foreach loop.
i would fire up nuget and get the JSON.net package
https://www.nuget.org/packages/Newtonsoft.Json/
http://james.newtonking.com/json
it is well documented and can save you a tonne of work.
see also http://json2csharp.com/
EDIT: you are already using this

Json.Net - Serialize property name without quotes

I'm trying to get Json.Net to serialise a property name without quote marks, and finding it difficult to locate documentation on Google. How can I do this?
It's in a very small part of a large Json render, so I'd prefer to either add a property attribute, or override the serialising method on the class.
Currently, the it renders like this:
"event_modal":
{
"href":"file.html",
"type":"full"
}
And I'm hoping to get it to render like: (href and type are without quotes)
"event_modal":
{
href:"file.html",
type:"full"
}
From the class:
public class ModalOptions
{
public object href { get; set; }
public object type { get; set; }
}
It's possible, but I advise against it as it would produce invalid JSON as Marcelo and Marc have pointed out in their comments.
Using the Json.NET library you can achieve this as follows:
[JsonObject(MemberSerialization.OptIn)]
public class ModalOptions
{
[JsonProperty]
public object href { get; set; }
[JsonProperty]
public object type { get; set; }
}
When serializing the object use the JsonSerializer type instead of the static JsonConvert type.
For example:
var options = new ModalOptions { href = "file.html", type = "full" };
var serializer = new JsonSerializer();
var stringWriter = new StringWriter();
using (var writer = new JsonTextWriter(stringWriter))
{
writer.QuoteName = false;
serializer.Serialize(writer, options);
}
var json = stringWriter.ToString();
This will produce:
{href:"file.html",type:"full"}
If you set the QuoteName property of the JsonTextWriter instance to false the object names will no longer be quoted.
You can also try a regex replace, with a substitution, which could handle any serialized object, and replace the quotes for you.
For Example:
var options = new ModalOptions { href = "file.html", type = "full" };
string jsonText = JsonConvert.SerializeObject(options);
string regexPattern = "\"([^\"]+)\":"; // the "propertyName": pattern
Console.WriteLine(Regex.Replace(jsonText, regexPattern, "$1:"));
This would produce:
{href:"file.html",type:"full"}
I built a working web example here.
Explanation of regex substitutions are here.

Categories