I'm trying to write a JSON file in C#, and I have a problem where I want to seperate each object with a comma (',') for it to be valid JSON, however I can't figure out how to do this. I've searched if there is a way you can search for a specific pattern in a string (in my case it would be '}{') and a regular expression might work, but I don't know how to create one.
The final result should look like
'},{'
instead of
'}{'.
Here is my code so far:
private void loopThroughArray()
{
string json = "";
for (int i = 0; i < array.Count; i++)
{
MyObject t = array[i];
json += new JavaScriptSerializer().Serialize(t);
//this writes the json to the file but without comma seperator
}
System.IO.File.WriteAllText(#"<MyFilepath>\json.txt", "{\"json\":[" + json + "]}");
//this writes the json to a file that and is in a json array called 'json'
}
I looked at different ways of serialising JSON as per #Measuring 's suggestion and discovered that this was the easiest method in my opinion:
json = JsonConvert.SerializeObject(MyObject);
Works perfectly, thanks #Measuring!
I agree with #Measuring it seems like an over complication to write your own when there are tools which can be used as identified in this answer.
Nonetheless you could do the following...
string json = "";
for (int i = 0; i < array.Count; i++){
MyObject t = array[i];
json += new JavaScriptSerializer().Serialize(t);
}
string pattern = "\}{\";
string replacement = "},{";
Regex rgx = new Regex(pattern);
string result = rgx.Replace(json, replacement);
What you are trying to do can be solved by string.Join and a bit of Linq
var serializer = new JavaScriptSerializer();
var json = string.Join( ",", array.Select( e => serializer.Serialize(e) );
Looks like this:
json += new JavaScriptSerializer().Serialize(t);
Is creating a {json object}. Your solution might be as easy as appending a , after like:
json += new JavaScriptSerializer().Serialize(t) + ",";
Edit (responding on your comment):
You can easily skip the last loop with an inner check.
json += new JavaScriptSerializer().Serialize(t);
if (i < array.Count - 1) json += ",";
Alternatively you could cut the for-loop 1 item short and add the last item after the loop.
It's far more efficient to use a StringBuilder than += and you should avoid creating reusable objects within loops.
Keeping as close to your code as possible, you could try:
private void loopThroughArray()
{
var serializer = new JavaScriptSerializer();
var json = new System.Text.StringBuilder();
for (int i = 0; i < array.Count; i++)
{
MyObject t = array[i];
json.Append(serializer.Serialize(t));
if (i < array.Count)
json.Append(",");
}
System.IO.File.WriteAllText(#"<MyFilepath>\json.txt", "{\"json\":[" + json.ToString() + "]}");
}
But it may be simpler to try:
private void loopThroughArray()
{
var serializer = new JavaScriptSerializer();
var json = serializer.Serialize(array);
System.IO.File.WriteAllText(#"<MyFilepath>\json.txt", "{\"json\":" + json.ToString() + "}");
}
But, if I were doing it I'd use Json.Net's JsonConvert on an anonymous type:
System.IO.File.WriteAllText(
#"<MyFilepath>\json.txt",
JsonConvert.SerializeObject(new {
json = array
}));
You can get Json.Net from nuget.
JsonNet is indeed easier to use, but in your case it feels like
JavaScriptSerializer works fine. Presumably you expect "{json:[...]}" as result - serializing new {json = array} instead of just array will produce that output:
var finalJson = new JavaScriptSerializer().Serialize(new {json = array});
Side note: please avoid manual string manipulation when constructing JSON or XML -it is not worth the effort and result in most cases is somewhat wrong.
Hi Kevin would it not be possible to replace the string using regex expressions,
/}{/g
and replace with
},{
Related
given an apparently invalid json
(which comes from google)
https://translate.googleapis.com/translate_a/single?client=gtx&sl=en&tl=de&dt=t&q=Science
of
[[["Wissenschaft","Science",,,2]],,"en"]
i want to get the values of Wissenschaft and Science
if figured out a very inelegant way to do it with Json.net via
string h = "[[[\"Wissenschaft\",\"Science\",,,2]],,\"en\"] ";
var obj = JsonConvert.DeserializeObject<List<dynamic>>(h);
JArray arr1 = obj[0];
var arr2 = arr1.First;
var x = arr2.First.Next;
string s = x.ToString();
is there some better, less verbose way ?
Here is a more concise version, maybe somebody has one which also retains
the other values from the top array
string h = "[[[\"Wissenschaft\",\"Science\",,,2]],,\"en\"]";
JsonSerializerSettings settings = new JsonSerializerSettings();
settings.Error = (serializer, err) =>
{
err.ErrorContext.Handled = true;
//ignore all errors
};
var obj = JsonConvert.DeserializeObject<List<List<List<dynamic>>>>(h,settings);
string strWissenschaft = obj[0][0][0];
string strScience = obj[0][0][1];
As you see i only care for the values in the most nested array, the other values are lost.
For first this is not valid JSON object but nevermind as you said Json.NET will parse it by adding null values into empty commas.
Because this is not valid object and it is just an array in some JSON format. There will probably no better way then parse it into dynamic List as you already did.
In case of { } at start and end and some keys:values format you can deserialize it into C# object according to class which you can define.
I have a string in my C# model populated with this string:
"[{\"ta_id\":97497,\"partner_id\":\"229547\",\"partner_url\":\"http://partner.com/deeplink/to/229547\"},{\"ta_id\":97832,\"partner_id\":\"id34234\",\"partner_url\":\"http://partner.com/deeplink/to/id34234\"}]"
Is there a way, using LINQ or RegEx, that I could parse out the partner_id's - so I ended up with a list object with:
229547
id34234
Thanks for your help, Mark
I have never used any JSON parser but if it comes to Regex you could try something like this:
private static void regexString()
{
string myString = "[{\"ta_id\":97497,\"partner_id\":\"229547\",\"partner_url\":\"http://partner.com/deeplink/to/229547\"},{\"ta_id\":97832,\"partner_id\":\"id34234\",\"partner_url\":\"http://partner.com/deeplink/to/id34234\"}]";
string[] stringList = Regex.Split(myString, "},{");
for (int i=0; i<stringList.Length ;i++)
{
stringList[i] = Regex.Split(Regex.Split(stringList[i], "partner_id\\\":\\\"")[1], "\\\",\\\"partner_url\\\"")[0];
}
}
Also there is a nice website to help you with creating your own regex patterns in the future, check it out:
gskinner.com
And a nice and short tutorial:
www.codeproject.com
Assuming your link having partner id always-
string Name = "[{\"ta_id\":97497,\"partner_id\":\"229547\",\"partner_url\":\"http://partner.com/deeplink/to/229547\"},{\"ta_id\":97832,\"partner_id\":\"id34234\",\"partner_url\":\"http://partner.com/deeplink/to/id34234\"}]";
string[] splittedString = Regex.Split(Name, "}");
List<string> allIds = new List<string>();
foreach (var i in splittedString)
{
var ids =Regex.Split(i, "/");
string id = ids[ids.Length - 1];
allIds.Add(id);
}
If that is the general format of the string then this regex should work
(?i)(?<=(partner_id).{5})\w+
Test here
This from your string will get
229547 and id34234
(?i) = Case insesitivity
(?<=(partner_id).{5}) = postive lookbehind for parter_id then any 5 characters which in this case will be \":\"
\w+ = Any alphanumeric characters one or more times
Hope this helped
Since this is JSON, you probably shouldn't bother trying to get a regex working. Instead, you can parse the JSON and then use LINQ.
using System.Web.Script.Serialization; // (in System.Web.Extensions.dll)
...
string s = "[{\"ta_id\":97497,\"partner_id\":\"229547\",\"partner_url\":\"http://partner.com/deeplink/to/229547\"},{\"ta_id\":97832,\"partner_id\":\"id34234\",\"partner_url\":\"http://partner.com/deeplink/to/id34234\"}]";
JavaScriptSerializer j = new JavaScriptSerializer();
object[] objects = (object[])j.DeserializeObject(s);
string[] ids = objects.Cast<Dictionary<string, object>>()
.Select(dict => (string)dict["partner_id"])
.ToArray();
It's a little messy to deserialize it to an object, because you don't have any type information. If you're not afraid of making a small class to deserialize into, you can do something like this:
class Foo
{
public string partner_id
{
get;
set;
}
}
...
JavaScriptSerializer j = new JavaScriptSerializer();
string[] ids = j.Deserialize<Foo[]>(s).Select(x => x.partner_id).ToArray();
Note that there are other options for deserializing JSON. I simply chose the most general-purpose one that's built in.
How can I get the length of a JSON Array I get using json.net in C#? After sending a SOAP call I get a JSON string as answer, I use json.net to parse it.
Example of the json I got:
{"JSONObject": [
{"Id":"ThisIsMyId","Value":"ThisIsMyValue"},
{"Id":"ThisIsMyId2","Value":"ThisIsMyValue2"}
]}
And I parse it and write it in console:
var test = JObject.Parse (json);
Console.WriteLine ("Id: {0} Value: {1}", (string)test["JSONObject"][0]["Id"], (string)test["JSONObject"][0]["Value"]);
This works like a spell, only I don't know the length of the JSONObject, but I need to do it in a for loop. I only have no idea how I can get the length of test["JSONObject"]
But something like test["JSONObject"].Length would be too easy I guess :(..
You can cast the object to a JArray and then use the Count property, like so:
JArray items = (JArray)test["JSONObject"];
int length = items.Count;
You can then loop the items as follows:
for (int i = 0; i < items.Count; i++)
{
var item = (JObject)items[i];
//do something with item
}
According to Onno (OP), you can also use the following:
int length = test["JSONObject"].Count();
However, I have not personally confirmed that this will work
The easiest and cleanest way I found:
int length = test["JSONObject"].Count;
You can use below line to get the length of JSON Array in .Net (JArray) .
int length = ((JArray)test["jsonObject"]).Count;
Just try this:
var test= ((Newtonsoft.Json.Linq.JArray)json).Count;
This worked for me supposing the json data is in a json file.
In this case, .Length works but no intellisence is available:
public ActionResult Index()
{
string jsonFilePath = "C:\\folder\\jsonLength.json";
var configFile = System.IO.File.ReadAllText(jsonFilePath);
JavaScriptSerializer jss = new JavaScriptSerializer();
var d = jss.Deserialize<dynamic>(configFile);
var jsonObject = d["JSONObject"];
int jsonObjectLength = jsonObject.Length;
return View(jsonObjectLength);
}
Is there a straightforward way of converting:
string str = "a=1,b=2,c=3";
into:
dynamic d = new { a = 1, b = 2, c = 3 };
I think I could probably write a function that splits the string and loops the results to create the dynamic object. I was just wondering if there was a more elegant way of doing this.
I think if you convert the "=" into ":" and wrap everything with curly brackets you'll get a valid JSON string.
You can then use JSON.NET to deserialize it into a dynamic object:
dynamic d = JsonConvert.DeserializeObject<dynamic>(jsonString);
You'll get what you want.
You may use Microsoft Roslyn (here's the all-in-one NuGet package):
class Program
{
static void Main(string[] args)
{
string str = "a=1,b=2,c=3,d=\"4=four\"";
string script = String.Format("new {{ {0} }}",str);
var engine = new ScriptEngine();
dynamic d = engine.CreateSession().Execute(script);
}
}
And if you want to add even more complex types:
string str = "a=1,b=2,c=3,d=\"4=four\",e=Guid.NewGuid()";
...
engine.AddReference(typeof(System.Guid).Assembly);
engine.ImportNamespace("System");
...
dynamic d = engine.CreateSession().Execute(script);
Based on the question in your comment, there are code injection vulnerabilities. Add the System reference and namespace as shown right above, then replace the str with:
string str =
#" a=1, oops = (new Func<int>(() => {
Console.WriteLine(
""Security incident!!! User {0}\\{1} exposed "",
Environment.UserDomainName,
Environment.UserName);
return 1;
})).Invoke() ";
The question you described is something like deserialization, that is, contructing objects from data form(like string, byte array, stream, etc). Hope this link helps: http://msdn.microsoft.com/en-us/library/vstudio/ms233843.aspx
Here's a solution using ExpandoObject to store it after parsing it yourself. Right now it adds all values as strings, but you could add some parsing to try to turn it into a double, int, or long (you'd probably want to try it in that order).
static dynamic Parse(string str)
{
IDictionary<String, Object> obj = new ExpandoObject();
foreach (var assignment in str.Split(','))
{
var sections = assignment.Split('=');
obj.Add(sections[0], sections[1]);
}
return obj;
}
Use it like:
dynamic d = Parse("a=1,b=2,c=3");
// d.a is "1"
I am trying to write code that will pull in, read, and separate a csv file. It has four columns with no titles. I've been searching for hours online and no one really seems to have the answer so I'm hoping that someone here can. After it is read in I need it to be able to be pulled very specifically as it is part of design. Thanks ahead of time!
Your question is a little vague, but I'll try and answer it as best I can.
A CSV file is (by definition) a file containing comma seperated values - the key here is that a comma is used as the delimiter. Personally, I find that using a different delimiter is prone to less nasties when parsing.
I've created the following test CSV file:
Column1,Column2,Column3,Column4
Row1Value1,Row1Value2,Row1Value3,Row1Value4
Row2Value1,Row2Value2,Row2Value3,Row2Value4
Row3Value1,Row3Value2,Row3Value3,Row3Value4
Row4Value1,Row4Value2,Row4Value3,Row4Value4
Row5Value1,Row5Value2,Row5Value3,Row5Value4
Here's some code to read that file into some simple structures that you can then manipulate. You might want to extend this code by creating classes for the columns and rows (and values as well).
string sFileContents = "";
using (StreamReader oStreamReader = new StreamReader(File.OpenRead("Test.csv")))
{
sFileContents = oStreamReader.ReadToEnd();
}
List<string[]> oCsvList = new List<string[]>();
string[] sFileLines = sFileContents.Split(Environment.NewLine.ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
foreach (string sFileLine in sFileLines)
{
oCsvList.Add(sFileLine.Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries));
}
int iColumnNumber = 0;
int iRowNumber = 0;
Console.WriteLine("Column{0}, Row{1} = \"{2}\"", iColumnNumber, iRowNumber, oCsvList[iColumnNumber][iRowNumber]);
iColumnNumber = 4;
iRowNumber = 2;
Console.WriteLine("Column{0}, Row{1} = \"{2}\"", iColumnNumber, iRowNumber, oCsvList[iColumnNumber][iRowNumber]);
Keep in mind that values are accessed by the column number, and then the row number.
I hope this helps.
All you need to do is simply convert it into a byte[] array and back into a string[builder?]. Then seperate each entry, and parse it like so.
http://www.digitalcoding.com/Code-Snippets/C-Sharp/C-Code-Snippet-Convert-file-to-byte-array.html
And to convert to a string:
// C# to convert a byte array to a string.
byte [] dBytes = ...
string str;
System.Text.UTF8Encoding enc = new System.Text.UTF8Encoding();
str = enc.GetString(dBytes);
You have to understand you need to make a parser. I made one to pull in Yahoo Stocks, basically splitting the colons into data.
This is a much simpler way to do what you want.
var lineCount = File.ReadLines(#"C:\file.txt").Count();
var reader = new StreamReader(File.OpenRead(#"C:\location1.csv"));
int[,] properties = new int[lineCount,4];
for(int i2 = 0; i2 < 4; i2++)
{
for(int i = 0; i < lineCount; i++)
{
var line = reader.ReadLine();
var values = line.Split(';');
properties[i,i2] = Convert.ToInt32(values[i2];
}
}