Is there in JSON function which dumps JSON array of dictionary into tab separated text files - json

I have an JSON array as defined below:-
[
{"Name":"Ayush","Age":24,"Job":"Developer"},
{"Name":"Monika","Age":23,"Job":"Developer"},
{"Name":"Chinmay","Age":23,"Job":"Developer"}
]
I want to dump this into text file in following format:-
Name Age Job
Ayush 24 Developer
Monika 23 Developer
Chinmay 23 Developer
Is there any C# function to accomplish the above? If not, how can i achieve it with minimum memory consumption?
Thanks in advance

There is no such built-in function. You may achieve this by reading JTokens from input stream using JsonTextReader and writing their values into another stream. Stream input and output ensures minimal memory footprint.
using (var inputStream = File.OpenRead("input.json"))
using (var streamReader = new StreamReader(inputStream))
using (var jsonTextReader = new JsonTextReader(streamReader))
using (var outputStream = File.OpenWrite("output.csv"))
using (var streamWriter = new StreamWriter(outputStream))
{
var firstItem = true;
while (jsonTextReader.Read())
{
if (jsonTextReader.TokenType == JsonToken.StartObject)
{
var jObject = JObject.ReadFrom(jsonTextReader);
if (firstItem)
{
streamWriter.WriteLine(string.Join("\t",
jObject.Children().Select(c => (c as JProperty).Name)));
firstItem = false;
}
streamWriter.WriteLine(string.Join("\t",
jObject.Values().Select(t => t.ToString())));
}
}
}
Demo: https://dotnetfiddle.net/2fCRa6. (I used MemoryStream and Console instead of input and output file streams in this demo since .NET Fiddle does not allow file IO, but the idea is the same.)

You can create a class with Name, Age and Job as properties.
public class Info{
public string Name { get; set; }
public int Age { get; set; }
public string Job { get; set; }
}
Then in another function use we can use System.Web.Script.Serialization class(to use this class make sure you have referenced System.Web.Extensions in project references). Once done we can use JavaScriptSerializer class and get list of objects from the json data. Then we can iterate over each item and add it two our file with a tab as a delimeter.
public static void WriteDetailsInFile(string jsonData)
{
var list = new JavaScriptSerializer().Deserialize<List<Info>>(jsonData);
using (var streamWriter = File.AppendText("D:MyFile.txt"))
{
streamWriter.WriteLine("Name\tAge\tJob");
foreach (var item in list)
{
streamWriter.WriteLine(item.Name + "\t" + item.Age + "\t" + item.Job);
}
}
}
//driver
public static void Main()
{
string data = #"[
{ ""Name"":""Ayush"",""Age"":24,""Job"":""Developer""},
{ ""Name"":""Monika"",""Age"":23,""Job"":""Developer""},
{ ""Name"":""Chinmay"",""Age"":23,""Job"":""Developer""}
]";
WriteDetailsInFile(data);
}

Related

.NET 6 - Change Json Property Casing

How can I change the casing of the property names of a json without performing model binding?
JsonElement serialization ignores PropertyNaming JsonSerializer options as is also confirmed here: https://github.com/dotnet/runtime/issues/61843
The suggested use of JsonNode/JsonObject results in the same behavior.
Any hints how I can accomplish this?
As example I want to change this:
{
"MyPoperty" : 5,
"MyComplexProperty" : {
"MyOtherProperty": "value",
"MyThirdProperty": true
}
}
to this:
{
"myPoperty" : 5,
"myComplexProperty" : {
"myOtherProperty": "value",
"myThirdProperty": true
}
}
Cheers.
I think you try to use Newtonsoft json
class Person
{
public string UserName { get; set; }
public int Age { get; set; }
}
coding
static void Main(string[] args)
{
Person person = new Person();
person.UserName = "Bob";
person.Age = 20;
var serializerSettings = new JsonSerializerSettings();
serializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
var json = JsonConvert.SerializeObject(person, serializerSettings);
Console.WriteLine(json);
}
output
{"userName":"Bob","age":20}
not depend on Newtonsoft json but in the case of multi-layer objects
var json = #"{""ShouldWindUpAsCamelCase"":""does it?""}";
var obj = JsonSerializer.Deserialize<Dictionary<string,string>>(json);
var dic = new Dictionary<string, string>();
foreach (var item in obj)
{
dic.Add(item.Key.FirstCharToLower(), item.Value);
}
var serialized = System.Text.Json.JsonSerializer.Serialize(dic);
Console.WriteLine(serialized);
FirstCharToLower() function
public static string FirstCharToLower(this string input)
{
if (String.IsNullOrEmpty(input))
return input;
string str = input.First().ToString().ToLower() + input.Substring(1);
return str;
}
#output
{"shouldWindUpAsCamelCase":"does it?"}

Reading JSON values from web browser?

I have a random JSON generated online and I am able to print all the values. But how do I read each array separately? For example, the below JSON contains different attributes, how do I read the string name that is an array containing 4 values.
JSON reader:
public class JsonHelper
{
public static T[] getJsonArray<T>(string json)
{
string newJson = "{ \"array\": " + json + "}";
Wrapper<T> wrapper = JsonUtility.FromJson<Wrapper<T>>(newJson);
return wrapper.array;
}
[System.Serializable]
private class Wrapper<T>
{
public T[] array;
}
}
[System.Serializable]
public class RootObject
{
public string name;
public string height;
public string mass ;
}
The below script is used to access the JSON online through RESTApi GET service. I am able to receive the whole text but how I read one single value of name or height or mass?
Script:
using UnityEngine.Networking;
using System.Linq;
using System.Linq.Expressions;
using UnityEngine.UI;
using System.IO;
public class GetData : MonoBehaviour {
// Use this for initialization
void Start () {
StartCoroutine(GetNames());
}
IEnumerator GetNames()
{
string GetNameURL = "https://swapi.co/api/people/1/?format=json";
using(UnityWebRequest www = UnityWebRequest.Get(GetNameURL))
{
// www.chunkedTransfer = false;
yield return www.Send();
if(www.isNetworkError || www.isHttpError)
{
Debug.Log(www.error);
}
else
{
if(www.isDone)
{
string jsonResult = System.Text.Encoding.UTF8.GetString(www.downloadHandler.data);
Debug.Log(jsonResult); //I am getting the result here
}
}
}
}
}
Your API call to 'https://swapi.co/api/people/1/?format=json' returns a single object, not an array.
So after you get your json, you can access name and height etc like:
if (www.isDone)
{
string jsonResult = System.Text.Encoding.UTF8.GetString(www.downloadHandler.data);
Debug.Log(jsonResult); //I am getting the result here
RootObject person = JsonUtility.FromJson<RootObject>(jsonResult);
// then you can access each property
Debug.Log(person.name);
Debug.Log(person.height);
}

Outputting data to JSON file csharp (unity)

I can't figure out how to output a complex data type to JSON.
I constructed a data type which basically holds smaller data types, I have also assigned the data types to new data types so they all seem to have a reference. I have looked into outputting complex data but don't seem to be able to find a problem similar to mine. I will consider appending data but this method will be much simpler if I can output the data type successfully.
Save Data Code
[System.Serializable]
public class SaveData
{
public MapData mapData;
}
[System.Serializable]
public class TileData
{
public List<BlockData> blockData;
}
[System.Serializable]
public class BlockData
{
public Vector3 blockPosition;
public string blockName;
public float blockOrientation;
public int blockLayer;
}
[System.Serializable]
public class MapData
{
public List<TileData> tileData;
}
Get Map Data Method
SaveData GetMapData()
{
mapHeight += mapStartY;
maplength += mapStartX;
int tileCounter = 0;
MapData mapData = new MapData();
SaveData saveData = new SaveData();
List<TileData> tileList = new List<TileData>();
for (float r = mapStartY; r < mapHeight; r++)
{
for(float c = mapStartX; c < maplength; c++)
{
Vector2 currentPosition = new Vector2(c * (blocksize)-(blocksize/2), blocksize * r -(blocksize/2));
GameObject[] currentTile = getObjectID.RayDetectAll(currentPosition);
if (currentTile!= null)
{
//adds a tiledata list here if the tile is occupied.
TileData tileData = new TileData();
//adds a list of blocks here.
List<BlockData> blocks = new List<BlockData>();
for (int i = 0; i < currentTile.Length; i++)
{
BlockData blockData = new BlockData();
GameObject currentBlock = currentTile[i];
blockData.blockPosition = currentBlock.transform.position;
blockData.blockName = currentBlock.name;
blockData.blockOrientation = currentBlock.transform.eulerAngles.z;
blockData.blockLayer = currentBlock.GetComponent<SpriteRenderer>().sortingOrder;
//adds a blockdata to the blocks list
blocks.Add(blockData);
Debug.LogWarning(blockData.blockName);
}
//need to assign tile data and add a new one to the list
tileList.Add(tileData);
//assins the blocks to tile data block data list
tileData.blockData = blocks;
}
else
{
//Debug.LogWarning("warning! no objects found on tile: " + currentPosition);
}
tileCounter++;
}
}
'''
I want the file to output all the data so that i can read the data and reassign it. Right now it outputs the data wrong.
Generally I think this is something that would be commented, but I can't comment yet.
If all you want is to convert an object to Json, could you use JsonUtility.ToJson() as described here?
just to let people know I devised a new method which counted an array of all tiles and assigned it to a data type with an array in it. It managed to load from this format.

Exclude a data member from JSon serialization

This is with the Docusign Rest api. When I call ToJson() on an EnvelopeDefinition, it returns the correct info, but I would like it to not serialize the base64 array for when I am writing this out to a log file. I tried using the [JsonIgnore] directive, but that stopped the array from being serialized altogether. Do I need to override the Serialize method on this class or just create another method, something like ToJsonForLogging() and not serialize that array?
I have created an extension method that will work for you. You can call this extension method in your code as follows
string json = envelopeDefinition.ToJsonLog(logDocumentBase64:false)
I am copying the DocumentBase64 into a temporary List and then using .ToJson() function to log without the documentBase64 property.
public static class EnvelopeDefinitionExtensions
{
public static string ToJsonLog(this EnvelopeDefinition envDefinition, bool logDocumentBase64 = true)
{
if (logDocumentBase64) return envDefinition.ToJson();
var tempDocumentBase64List = new List<string>();
foreach(var doc in envDefinition.Documents)
{
tempDocumentBase64List.Add(doc.DocumentBase64);
doc.DocumentBase64 = null;
}
string json = envDefinition.ToJson();
int i =0;
foreach(var doc in envDefinition.Documents)
{
doc.DocumentBase64 = tempDocumentBase64List[i];
i++;
}
return json;
}
}

Json file generation using Javascript serializer

I need to generate the following json files using Javascript serializer,
1. {"components":[{"name":"AA"}]}
2. {"customfield_10222":[{"name":"xxx"},{"name":"yyyy"}]} // this custom field represents the additional notification persons.
I have to achieve this scenario using the below coding,
public List<AdditionalUsers> AdditionalNotification = new List<AdditionalUsers>();
public List<ComponentsDetails> Component = new List<ComponentsDetails>();
class AdditionalUsers
{
public string name;
}
class ComponentsDetails
{
public string name;
}
string[] a=new string[2]{"XXX","YYY"};
foreach (string additionalUser in a)
{
AdditionalNotification.Add(new AdditionalUsers() { name =additionalUser });
}
Component.Add(new ComponentsDetails() { name = "AA" });
var subFields = new Dictionary<string, object>();
subFields.Add("components", Component); // represents 1 json file
subFields.Add("customfield_10222", AdditionalNotification); // represents 2 json file
JavaScriptSerializer serializer = new JavaScriptSerializer();
string json = serializer.Serialize((Object)subFields);
Console.WriteLine(json);
The result like this
{
"components":[{"name": "AA"}],
"customfield_10222":[{"name":"XXX"},{"name":"YYY"}]
}