How would i keep appending data?
I have this:
{
"13232": [
"2012952"
]
}
And i want to add an another object to it, example:
{
"13232": [
"2012952"
],
"19213": [
"2016086"
]
}
This is the code i use:
JArray array = new JArray();
array.Add(Itemid);
JObject o = new JObject();
o[Userid] = array;
string json = o.ToString(Formatting.Indented);
//i know this keeps appending text but how would i append it inside the { and }?
File.AppendAllText("E:/media.json", json);
I literally have no idea how to keep adding it, but maybe someone else has?
You won't be able to use file append operations to do this. File append operations can only add text to the end, they can't insert text at some point in the middle. This makes it impossible to use file-append to keep the JSON valid.
You have two choices that I can think of:
Read the entire file into an object, add your object, and then
rewrite the entire file (poor performance)
Open the file read/write, parse through
until you get to the closing curly brace, then write the remaining
data, then write the close curly brace (not trivial)
The safest approach is read-update-rewrite (applies to JSON and XML format as they don't support appending).
Next option if you can live with invalid JSON is to simply concatenate JSON fragments with code you have and than use SupportMultipleContent in JsonReader to read fragments Read Multiple Fragments With JsonReader
If those approaches don't work and your format is fixed - find position of last ] in the file, seek stream there and write new array elements and append ]}.
I recommand you use Newtonsoft Json lib, available as a nuget package.
You can the make a model class to represent on of the json node then you can de-serialize you Json to that model and build an array containing the new element at the end to then re-serialize it to json after.
Look at this MSDN page about it: https://msdn.microsoft.com/en-us/library/bb412179(v=vs.110).aspx
Edit: Actual NewtonSoft Documentation
In steps: 1 Deserialize the collection
2: And a new class instance with listName.Add(className);
3: Reserialize the collection
My approach was to add an additional step to my string handling.
public void WriteObjectToFile(object objectToInsert)
{
var stringToSaveToFile = JsonConvert.SerializeObject(objectToInsert) + ",";
File.AppendAllText(this.path, stringToSaveToFile);
}
public List<objects> GetListFromFile()
{
var notQuiteJSONstring = File.ReadAllTest(this.path);
var treatment1 = notQuiteJSONstring.Substring(0, notQuiteJSONstring.Length -1); //remove the trailing comma
var treatment2 = "[" + treatment1 + "]"; // wrap string with brackets to deserialize as list
var list = JsonConvert.DeserializeObject<List<object>>(treatment2);
return list;
}
Related
Say I have a string representing an array of objects in JSON form:
string s = "[{\"name\":\"Person1\"},{\"name\":\"Person2\"}]";
What I want is an array of strings, each string being the string representation of a JSON object - NOT the object itself. It should look something like this:
string[] s = new string[]
{
"{\"name\":\"Person1\"}",
"{\"name\":\"Person2\"}"
};
1) Almost every search I attempt pulls up millions of results on how to simply deserialize a JSON string using (eg) Json.NET. This is not what I want to do.
2) I have tried building a class representing the objects to temporarily loop through a deserialize/serialize mapping each to a string in an array, but the schema for the objects is variable (hence why I only need a string representation).
3) I have attempted a few regex to try and do this, but my JSON string can contain fields that contain JSON strings as their value (icky, but out of my control) and so nested character escaping etc drove me partially mad before I decided to beg for help here.
Surely this should be simple? Anybody got any pointers?
You'll need to deserialize it, and then serialize each object independently.
For example (using Newtonsoft.Json):
string json = "[{\"name\":\"Person1\"},{\"name\":\"Person2\"}]";
var objects = JsonConvert.DeserializeObject<List<object>>(json);
var result = objects.Select(obj => JsonConvert.SerializeObject(obj)).ToArray();
Yields (as a string[]):
{"name":"Person1"}
{"name":"Person2"}
If you try to avoid deserializing and serializing, you're almost certain to run into an edge case that will break your code.
string s = "[{\"name\":\"Person1\"},{\"name\":\"Person2\"}]";
var Json = JsonConvert.DeserializeObject<List<object>>(s);
string[] Jsonn = Json.Select(x => x.ToString()).ToArray();
[] Jsonn returns string array instead of object array with JObject formatted.
Hope this one help you.
Why don't you just use this
string s = "[{\"name\":\"Person1\"},{\"name\":\"Person2\"}]";
string[] t = s.Split(',');
I tried it. It simply gives you string array as you want it....
I am converting from XML to JSON using SerializeXmlNode. Looks the expected behavior is to convert all XML values to strings, but I'd like to emit true numeric values where appropriate.
// Input: <Type>1</Type>
string json = JsonConvert.SerializeXmlNode(node, Newtonsoft.Json.Formatting.Indented, true);
// Output: "Type": "1"
// Desired: "Type": 1
Do I need to write a custom converter to do this, or is there a way to hook into the serialization process at the appropriate points, through delegates perhaps? Or, must I write my own custom JsonConverter class to manage the transition?
Regex Hack
Given the complexity of a proper solution, here is another (which I'm not entirely proud of, but it works...).
// Convert to JSON, and remove quotes around numbers
string json = JsonConvert.SerializeXmlNode(node, Newtonsoft.Json.Formatting.Indented, true);
// HACK to force integers as numbers, not strings.
Regex rgx = new Regex("\"(\\d+)\"");
json = rgx.Replace(json, "$1");
XML does not have a way to differentiate primitive types like JSON does. Therefore, when converting XML directly to JSON, Json.Net does not know what types the values should be, short of guessing. If it always assumed that values consisting only of digits were ordinal numbers, then things like postal codes and phone numbers with leading zeros would get mangled in the conversion. It is not surprising, then, that Json.Net takes the safe road and treats all values as string.
One way to work around this issue is to deserialize your XML to an intermediate object, then serialize that to JSON. Since the intermediate object has strongly typed properties, Json.Net knows what to output. Here is an example:
class Program
{
static void Main(string[] args)
{
string xml = #"<root><ordinal>1</ordinal><postal>02345</postal></root>";
XmlSerializer xs = new XmlSerializer(typeof(Intermediary));
using (TextReader reader = new StringReader(xml))
{
Intermediary obj = (Intermediary)xs.Deserialize(reader);
string json = JsonConvert.SerializeObject(obj , Formatting.Indented);
Console.WriteLine(json);
}
}
}
[XmlRoot("root")]
public class Intermediary
{
public int ordinal { get; set; }
public string postal { get; set; }
}
Output of the above:
{
"ordinal": 1,
"postal": "02345"
}
To make a more generic solution, yes, you'd have to write your own converter. In fact, the XML-to-JSON conversion that takes place when calling SerializeXmlNode is done using an XmlNodeConverter that ships with Json.Net. This converter itself does not appear to be very extensible, but you could always use its source code as a starting point to creating your own.
I have JSON text like this :
...
"simples":{
"AS100ELABQVKANID-91057":{
"meta":{
"sku":"AS100ELABQVKANID-91057",
"price":"3669000.00",
"original_price":"3379000.00",
"special_to_date":"2015-03-19 23:59:59",
"shipment_type":"1",
"special_price":"3299000.00",
"tax_percent":"10.00",
"sourceability":"Sourceable",
"quantity":"15",
"variation":"...",
"package_type_position":"0",
"min_delivery_time":"1",
"max_delivery_time":"3",
"attribute_set_name":"electronics",
"3hours_shipment_available":false,
"estimated_delivery":"",
"estimated_delivery_position":""
},
"attributes":{
"package_type":"Parcel"
}
}
},
"description":
...
The above text appears repeatedly in my JSON text. I am trying to build every result to this :
"simples":[],"description"
So far, I have made this regex :
\"simples\":{(?:.*v(?:|=)|(?:.*)?)},\"description\"
But the result is cut everything from my first "simples" into last "description".
Regex newbie here.
Thanks in advance
I recommend parsing the JSON, replacing the value, then re-stringifying it
var obj = JSON.parse(json);
obj.simples = [];
json = JSON.stringify(obj);
Using a regexp for this is pure insanity
Don't use Regex to parse JSON; use a JSON parser.
Here is how you can do this using JSON.Net, assuming the object containing simples is part of a flat list of results:
JArray array = JArray.Parse(json);
foreach (JObject obj in array)
{
obj["simples"].Parent.Remove();
}
json = array.ToString();
If your JSON is more complicated (i.e. "simples" can appear at more than one level in the JSON), then you will need a recursive search to find and remove it. This answer has a helper method that can find a specific property by name anywhere in the JSON and return a list of all occurrences. Once you have the list of occurrences, you can then loop through them and remove them as shown above.
Hi How do I retrieve the number from the following string,
{"number":100,"data":[test]}
The number could be of any length.
I used the following code. but it gives and error message
strValue.Substring((strValue.IndexOf(":")+1), (strValue.IndexOf("data")));
the output comes like
100,"data":[
Thanks,
It looks like your input string is JSON. Is it? If so, you should use a proper JSON parser library like JSON.NET
As noted by Jon, your input string seems to be a JSON string which needs to be deserialized. You can write your own deserializer, or use an existing library, such as Json.NET. Here is an example:
string json = #"[
{
""Name"": ""Product 1"",
""ExpiryDate"": ""\/Date(978048000000)\/"",
""Price"": 99.95,
""Sizes"": null
},
{
""Name"": ""Product 2"",
""ExpiryDate"": ""\/Date(1248998400000)\/"",
""Price"": 12.50,
""Sizes"": null
}
]";
List<Product> products = JsonConvert.DeserializeObject<List<Product>>(json);
Your attempt is close. There are two (possibly three issues) I found.
Your string has a comma after the number you're looking for. Since your code is searching for the index of "data", your end index will end up one character too far.
The second paramter of String.Substring(int, int) is actually a length, not an end index.
Strings are immutable in C#. Because of this, none of the member functions on a string actually modify its value. Instead, they return a new value. I don't know if your code example is complete, so you may be assigning the return value of SubString to something, but if you're not, the end result is that strValue remains unchanged.
Overall, the result of your current call to string.Substring is returning 100,"data":[tes. (and as far as I can see, it's not storing the result).
Try the following code:
string justTheNumber = null;
// Make sure we get the correct ':'
int startIndex = strValue.IndexOf("\"number\":") + 9;
// Search for the ',' that comes after "number":
int endIndex = strValue.IndexOf(',', startIndex);
int length = endIndex - startIndex;
// Note, we could potentially get an ArguementOutOfRangeException here.
// You'll want to handle cases where startPosition < 0 or length < 0.
string justTheNumber = strValue.Substring(startIndex, length);
Note: This solution does not handle if "number": is the last entry in the list inside your string, but it should handle every other placement in it.
If your strings get more complex, you could try using Regular Expressions to perform your searches.
Parsing JSON spring in that way is very bad practice as everything is hardcoded. Have you though of using 3rd party library for parsing JSON strings, like Newtonsoft JSON.
I guess you needed to use IndexOf(",") istead of IndexOf("data")
so I'm fairly new to programming but am looking to go much deeper with it. I recently started to get involved in a project to create a WinForm program for a website that uses an API system in JSON.
I've never used an API before so I'm not quite sure how it works but after looking at it for a few minutes I seem to have the gist of it. What I don't get is how exactly parsing JSON in C# works.
I found
this link after a little google searching. And I got it working (somewhat) with this code.
static void Main(string[] args)
{
WebClient c = new WebClient();
var vLogin = c.DownloadString("https://www.openraid.us/index.php/api/login/username/password");
//Returns string
//{"status":1,"error":null,"token":"250-1336515541-c48d354d96e06d488d1a2530071ef07c9532da26"}
//Token = random, no decisive length*/
JObject o = JObject.Parse(vLogin);
Console.WriteLine("Login Status: " + o["status"]);
String sToken = "" + o["token"];
Console.WriteLine(sToken);
Console.WriteLine("");
//Breaks after this
var myRaids = c.DownloadString("https://www.openraid.us/index.php/api/myraids/"+sToken);
JObject r = JObject.Parse(myRaids); //error occurs here
String sEventId = "" + r["event_id"];
Console.WriteLine("Event ID: " + sEventId);
Console.ReadLine();
}
So to me it looks like I have parsing 1 page done and handled, but when I move onto the second I get this error.
Error reading JObject from JsonReader. Current JsonReader item is not an object: StartArray. Path '', line 1, position 1.
So I guess my question is, how do I parse more than 1 page or call of JSON and what would be the easiest way to break up each section of the JSON object (Such as status, error, and token, into C# strings?
Did you try to JArray instead? Depending on what kind of object you are trying to return
WebClient client = new WebClient();
var data = client.DownloadString("");
var jArray = JArray.Parse(data);
JSON requires brackets for arrays and commas between multiple objects.
This is per the JSON standard. I also recommend using JSON.net via NuGet instead of the native JSON parser unless it is overkill and you cannot have the extra bloat.
For example, your parsing a file with two seperate JSON objects - the following does not work per the JSON standard (lacks a comma between the 2 objects and the two objects are not encapsulated by brackets):
{"status":1,"error":null}
{"status":2,"error":null}
The following 3 JSON objects parsed from a file does work (has brackets for multiple objects and commas between objects):
[{"glossary": {"title": "fun glossary","SeeAlso": ["GML", "XML"]},
{"glossary": {"title": "grey glossary","SeeAlso": ["GML", "XML"]},
{"glossary": {"title": "blue glossary","SeeAlso": ["GML", "XML"]}]
You can cut every JSON object(Array) into more object using for loops
the C# API is System.Json
var jsonArray = JsonArray.Parse(st);//st is the string which contain the JSON objects
foreach (var item in jsonArray) {
JsonObject ob = new JsonObject(item);
foreach (var t in ob.Values) {
JsonObject oo = new JsonObject(t);
foreach (var x in oo) {
textBox1.AppendText(x.Key + ā : ā + x.Value + ā\nā);
}
}
}