c# Json get value from list sourced from usgs url - c#

I need help extracting and returning values from json as either doubles or string, either should be fine.
The URL being used it: <https://earthquake.usgs.gov/ws/designmaps/asce7-16.json?latitude=34&longitude=-118&riskCategory=III&siteClass=C&title=Example>
here is the json
{
"request": {
"date": "2021-01-30T19:07:52.176Z",
"referenceDocument": "ASCE7-16",
"status": "success",
"url": "https://earthquake.usgs.gov/ws/designmaps/asce7-16.json?latitude=34&longitude=-118&riskCategory=III&siteClass=C&title=Example",
"parameters": {
"latitude": 34,
"longitude": -118,
"riskCategory": "III",
"siteClass": "C",
"title": "Example"
}
},
"response": {
"data": {
"pgauh": 0.819,
"pgad": 1.021,
"pga": 0.819,
"fpga": 1.2,
"pgam": 0.983,
"ssrt": 1.888,
"crs": 0.896,
"ssuh": 2.106,
"ssd": 2.432,
"ss": 1.888,
"fa": 1.2,
"sms": 2.265,
"sds": 1.51,
"sdcs": "D",
"s1rt": 0.669,
"cr1": 0.9,
"s1uh": 0.743,
"s1d": 0.963,
"s1": 0.669,
"fv": 1.4,
"sm1": 0.936,
"sd1": 0.624,
"sdc1": "D",
"sdc": "D",
"tl": 8,
"t-sub-l": 8,
"cv": 1.278,
...
url is defined as an input and Ss and S1 are defined as outputs per VisualStudio 2019 grasshopper developer C# template.
right now Ss and S1 return null values, they should return 1.888 and 0.669, respectively.
using Grasshopper.Kernel;
using System;
using System.Net;
using Newtonsoft.Json.Linq;
protected override void SolveInstance(IGH_DataAccess DA)
{
string url = "";
DA.GetData(0, ref url);
using (WebClient wc = new WebClient())
{
var json = wc.DownloadString(url);
JObject jObj = JObject.Parse(json); // Parse the object graph
string Ss = (string)jObj["ss"];
string S1 = (string)jObj["s1"];
//Functions I also tried
//var data = jObj["data"];
//foreach (var d in data) ;
//var Ss = d["ss"];
//double Ss = jObj.GetValue("ss").ToObject<double>();
//string Ss = jObj.GetValue("ss").Value<string>();
//string Ss = jObj.GetValue("ss").ToString();
//string Ss = jObj["ss"].ToString();
DA.SetData(0, Ss);
DA.SetData(1, S1);
}
}

The information you are looking for is nested in two levels, you have to access the response object then the data object, this should work:
var json = wc.DownloadString(url);
JObject jObj = JObject.Parse(json); // Parse the object graph
var data = jObj["response"]["data"];
var ss = data["ss"].ToObject<double>(); // or .ToString() if you want the string value
var s1 = data["s1"].ToObject<double>(); // or .ToString() if you want the string value
DA.SetData(0, ss);
DA.SetData(1, s1);
note: this code lacks null checks and error handling (try-catch block) for the sake of simplicity. But you need to add that in your code.

your data is null, is because your need Deserilize Json
using httpclientFactory
var httpclient = _httpClientFactory.CreateClient();
var responseDatas = await httpclient.GetAsync("https://earthquake.usgs.gov/ws/designmaps/asce7-16.json?latitude=34&longitude=-118&riskCategory=III&siteClass=C&title=Example");
if (responseDatas.IsSuccessStatusCode)
{
var responseDatasJson = await responseDatas .Content.ReadAsStringAsync();
var options = new JsonSerializerOptions() { PropertyNameCaseInsensitive = true };
var resultDataJson = JsonSerializer.Deserialize<Root>(responseDatasJson, options);
return (resultDataJson);
}
for convert json to c# class use this site Json to c# class
or use visual studio options
Edit-->Paste Special-->Paste Json As Classes
public class Data {
public double ss{ get; set; }
public double s1{ get; set; }
....your properties
}
public class Response {
public Data data { get; set; }
}
public class Root {
public Response response { get; set; }
}

Related

.NET 6 “core” Create Dynamic Object containing List<MyOtherDynamicListObject> [duplicate]

For some of my unit tests I want the ability to build up particular JSON values (record albums in this case) that can be used as input for the system under test.
I have the following code:
var jsonObject = new JObject();
jsonObject.Add("Date", DateTime.Now);
jsonObject.Add("Album", "Me Against The World");
jsonObject.Add("Year", 1995);
jsonObject.Add("Artist", "2Pac");
This works fine, but I have never really like the "magic string" syntax and would prefer something closer to the expando-property syntax in JavaScript like this:
jsonObject.Date = DateTime.Now;
jsonObject.Album = "Me Against The World";
jsonObject.Year = 1995;
jsonObject.Artist = "2Pac";
Well, how about:
dynamic jsonObject = new JObject();
jsonObject.Date = DateTime.Now;
jsonObject.Album = "Me Against the world";
jsonObject.Year = 1995;
jsonObject.Artist = "2Pac";
You can use the JObject.Parse operation and simply supply single quote delimited JSON text.
JObject o = JObject.Parse(#"{
'CPU': 'Intel',
'Drives': [
'DVD read/writer',
'500 gigabyte hard drive'
]
}");
This has the nice benefit of actually being JSON and so it reads as JSON.
Or you have test data that is dynamic you can use JObject.FromObject operation and supply a inline object.
JObject o = JObject.FromObject(new
{
channel = new
{
title = "James Newton-King",
link = "http://james.newtonking.com",
description = "James Newton-King's blog.",
item =
from p in posts
orderby p.Title
select new
{
title = p.Title,
description = p.Description,
link = p.Link,
category = p.Categories
}
}
});
Json.net documentation for serialization
Neither dynamic, nor JObject.FromObject solution works when you have JSON properties that are not valid C# variable names e.g. "#odata.etag". I prefer the indexer initializer syntax in my test cases:
JObject jsonObject = new JObject
{
["Date"] = DateTime.Now,
["Album"] = "Me Against The World",
["Year"] = 1995,
["Artist"] = "2Pac"
};
Having separate set of enclosing symbols for initializing JObject and for adding properties to it makes the index initializers more readable than classic object initializers, especially in case of compound JSON objects as below:
JObject jsonObject = new JObject
{
["Date"] = DateTime.Now,
["Album"] = "Me Against The World",
["Year"] = 1995,
["Artist"] = new JObject
{
["Name"] = "2Pac",
["Age"] = 28
}
};
With object initializer syntax, the above initialization would be:
JObject jsonObject = new JObject
{
{ "Date", DateTime.Now },
{ "Album", "Me Against The World" },
{ "Year", 1995 },
{ "Artist", new JObject
{
{ "Name", "2Pac" },
{ "Age", 28 }
}
}
};
There are some environment where you cannot use dynamic (e.g. Xamarin.iOS) or cases in where you just look for an alternative to the previous valid answers.
In these cases you can do:
using Newtonsoft.Json.Linq;
JObject jsonObject =
new JObject(
new JProperty("Date", DateTime.Now),
new JProperty("Album", "Me Against The World"),
new JProperty("Year", "James 2Pac-King's blog."),
new JProperty("Artist", "2Pac")
)
More documentation here:
http://www.newtonsoft.com/json/help/html/CreatingLINQtoJSON.htm
Sooner or later you will have property with a special character. e.g. Create-Date. The hyphen won't be allowed in property name. This will break your code. In such scenario, You can either use index or combination of index and property.
dynamic jsonObject = new JObject();
jsonObject["Create-Date"] = DateTime.Now; //<-Index use
jsonObject.Album = "Me Against the world"; //<- Property use
jsonObject["Create-Year"] = 1995; //<-Index use
jsonObject.Artist = "2Pac"; //<-Property use
Simple way of creating newtonsoft JObject from Properties.
This is a Sample User Properties
public class User
{
public string Name;
public string MobileNo;
public string Address;
}
and i want this property in newtonsoft JObject is:
JObject obj = JObject.FromObject(new User()
{
Name = "Manjunath",
MobileNo = "9876543210",
Address = "Mumbai, Maharashtra, India",
});
Output will be like this:
{"Name":"Manjunath","MobileNo":"9876543210","Address":"Mumbai, Maharashtra, India"}
May I suggest using the nameof expression combined with a model for the structure you're trying to build?
Example:
record RecordAlbum(string Album, string Artist, int Year);
var jsonObject = new JObject
{
{ nameof(RecordAlbum.Album), "Me Against The World" },
{ nameof(RecordAlbum.Artist), "2Pac" },
{ nameof(RecordAlbum.Year), 1995 }
};
As an added benefit to removing the "magic string" aspect - this also will give you a little bit of refactor-ability. You can easily rename any given property name for the record and it should update the value returned by the nameof() expression.
You can use Newtonsoft library and use it as follows
using Newtonsoft.Json;
public class jb
{
public DateTime Date { set; get; }
public string Artist { set; get; }
public int Year { set; get; }
public string album { set; get; }
}
var jsonObject = new jb();
jsonObject.Date = DateTime.Now;
jsonObject.Album = "Me Against The World";
jsonObject.Year = 1995;
jsonObject.Artist = "2Pac";
System.Web.Script.Serialization.JavaScriptSerializer oSerializer =
new System.Web.Script.Serialization.JavaScriptSerializer();
string sJSON = oSerializer.Serialize(jsonObject );

json string creation with c#

I am creating a string variable to use in an rest post call and it is failing. when I debug and look at the json value I am told it is not in json format. It sure seems to be key:value pairs so I an not sure what the issue here is?
instead of double single quotes I also tried escaping the " by using \ like so (neither method is good it seems):
//string postData = "{\"title\":\"Change Title\", \"description\":\"Create description\", \"scheduledStartDate\": \"2018-12-24T11:24:48.91Z\", \"scheduledEndDate'': ''2018-12-25T11:24:48.91Z'' }";
string postData = #"{''changeNumberForClone'': ''C03688051'',
''scheduledStartDate'': ''2017-12-24T11:24:48.91Z'',
''scheduledEndDate'': ''2017-12-25T11:24:48.91Z''}";
Using NewtonSoft Json.NET, you could use the following code to obtain a correct json string:
Dictionary<String, String> jsonDict = new Dictionary<String, String>();
jsonDict.Add("changeNumberForClone", "C03688051");
jsonDict.Add("scheduledStartDate", "2017-12-24T11:24:48.91Z");
jsonDict.Add("scheduledEndDate", "2017-12-25T11:24:48.91Z");
String postData = JsonConvert.SerializeObject(jsonDict);
If you don't want to add a new library to your project:
String postData = "{\"changeNumberForClone\":\"C03688051\", \"scheduledStartDate\":\"2017-12-24T11:24:48.91Z\", \"scheduledEndDate\": \"2017-12-25T11:24:48.91Z\"}";
In order to produce json strings with multiple levels of depth using the same approach, you can use anonymous objects as follows:
var obj = new { abc = new { def = new { one="1", two="2" } } };
var json = JsonConvert.SerializeObject(obj);
or, if you prefer to use Dictionary instances:
var obj = new Dictionary<String,Object>()
{
{
"abc", new Dictionary<String,Object>()
{
{
"def" , new Dictionary<String,Object>()
{
{ "one", "1" }, {"two", "2" }
}
}
}
}
};
the output, for both approaches, would be the following:
{
"abc": {
"def" : {
"one": "1",
"two": "2",
},
}
}

Customizing the JSON received from Web API

I need to add one more node to Json string.
Following is the code from where I am reading the data.
var url = "https://xyz_12232_abc/0908978978979.json";
var sys = new WebClient();
var content = sys.DownloadString(url);
I received following output from above code:
{
"2312312312313":
{
"emailId":"abc#gmail.com",
"model":"XYZ001",
"phone":"+654784512547",
"userName":"User1"
},
"23456464512313":
{
"emailId":"abcd#gmail.com",
"model":"XYZ002",
"phone":"+98745114474",
"userName":"User2"
},
"45114512312313":
{
"emailId":"abcde#gmail.com",
"model":"XYZ3",
"phone":"+214784558741",
"userName":"User3"
}
}
But, I want this output like below:
{
"Records": [
{
"UID":"2312312312313":,
"emailId":"abc#gmail.com",
"model":"XYZ001",
"phone":"+654784512547",
"userName":"User1"
},
{
"UID":"23456464512313":,
"emailId":"abcd#gmail.com",
"model":"XYZ002",
"phone":"+98745114474",
"userName":"User2"
},
{
"UID":"45114512312313":,
"emailId":"abcde#gmail.com",
"model":"XYZ3",
"phone":"+214784558741",
"userName":"User3"
}
]
}
Now, how can it be achieved ?
You can use Json.NET to massage the data into your desired output:
var jsonStr = #"..."; // your JSON here
var obj = JsonConvert.DeserializeObject<Dictionary<string, JObject>>(jsonStr);
var formattedObj = new
{
Records = obj.Select(x =>
{
x.Value.AddFirst(new JProperty("UID", x.Key));
return x.Value;
})
};
// serialize back to JSON
var formattedJson = JsonConvert.SerializeObject(formattedObj);

C# JSON String to Web API

Currently facing an issue when making a JSON string in C# and trying to send it through to a web API using the WebClient.
Currently I have a few methods, first off the one that works. Using POSTMAN sending the following dataset of text through to the API works correctly:
POSTMAN Dataset - This Works in POSTMAN
{ "record":
{
"form_id": "efe4f66f-b57c-4497-a370-25c0f3d8746a",
"status": "240",
"latitude": -82.638039,
"longitude": 27.770787,
"form_values":
{
"833b": "99999",
"683b": "9999999",
"fa37": "Testing",
"b2e3": "Testing"
}
}
}
In C# I am using a few different ways to construct this sting with little success.
C# List Method - Newtonsoft.Json.Serialization
The first is building a List and then using Newtonsoft.Json to play with it:
List<Parent> DataList = new List<Parent>();
List<Child> Form = new List<Child.formvalues>();
var Formvals = new Child.formvalues
{
ActionDescription = Row.ActionDescription,
ActionNotes = Row.ActionNotes,
ActionID = Row.ActionID,
AssetID = Row.AssetID
};
Form.Add(Formvals);
var DataElement = new Parent
{
form_id = AppFormID,
latitude = Lat,
longitude = Long,
status = Row.Status,
form_values = Form
};
DataList.Add(DataElement);
string json = JsonConvert.SerializeObject(DataList.ToArray());
This code results in the following string:
[
{\"form_id\":\"efe4f66f-b57c-4497-a370-25c0f3d8746a\",
\"latitude\":-82.638039,
\"longitude\":27.770787,
\"status\":239,
\"form_values\":[
{\"833b\":99999,
\"683b\":9999999,
\"fa37\":\"Testing\",
\"b2e3\":\"Testing\"
}]
}
]
Another attempt I am trying is the following, which in my opinion is the closest so far:
C# - String Building Method
string Content = #"{ "
+ "\"record\": {"
+ "\"form_id\": "\"" + AppFormID + ""\","
+ "\"status\": "\"" + Row.Status + ""\","
+ "\"latitude\": "+ Lat + ","
+ "\"longitude\": "+ Long + ","
+ "\"form_values\": {"
+ "\"833b\": "\""+Row.AssetID +""\","
+ "\"683b\": "\""+Row.ActionID + ""\","
+ "\"fa37\": "\""+Row.ActionDescription + ""\","
+ "\"b2e3\": "\""+Row.ActionNotes + ""\""
+ "}"
+ "}"
+ "}";
That line results in:
{ \"record\":
{
\"form_id\": \"efe4f66f-b57c-4497-a370-25c0f3d8746a\",
\"status\": \"239\",
\"latitude\": -82.638039,
\"longitude\": 27.770787,
\"form_values\":
{
\"833b\": \"99999\",
\"683b\": \"9999999\",
\"fa37\": \"Testing\",
\"b2e3\": \"Testing\"
}
}
}
The Question!
So the question, is someone able to help me achieving the format in the first JSON that I put into POSTMAN exactly?
UPDATE - 6:40PM
Web client code c#
AppURLRef is set in code further up and appears to be correct in the debugger. json is the result of the tests.
var http = new WebClient();
http.Headers.Add(HttpRequestHeader.ContentType, "application/json");
var response = http.UploadString(AppURLRef, "POST", json);
Result of Update
"[{\"record\":{\"form_id\":\"efe4f66f-b57c-4497-a370-25c0f3d8746a\",
\"latitude\":-82.638039,
\"longitude\":27.770787,
\"status\":\"240\",
\"form_values\":
[{\"833b\":\"99999\",
\"683b\":\"9999999\",
\"fa37\":\"Testing\",
\"b2e3\":\"Testing\"}]}}]"
Try the following.
public class Record
{
[JsonProperty(PropertyName = "form_id")]
public string FormId { get; set; }
[JsonProperty(PropertyName = "status")]
public string Status { get; set; }
[JsonProperty(PropertyName = "latitude")]
public decimal Latitude { get; set; }
[JsonProperty(PropertyName = "longitude")]
public decimal Longitude { get; set; }
[JsonProperty(PropertyName = "form_values")]
public Dictionary<string, string> FormValues { get; set; }
}
public class RecordContainer
{
[JsonProperty(PropertyName = "record")]
public Record Record { get; set; }
}
Usage:
var container = new RecordContainer();
container.Record = new Record();
// Code to populate values
JsonConvert.SerializeObject(container);
I am using Newtonsoft Json to serialize and I get the same output that you have asked for.
I'd try the following along with NewtonSoft.JSON.
var data = new
{
record = new
{
form_id = "efe4f66f-b57c-4497-a370-25c0f3d8746a",
status = "240",
latitude = -82.638039,
longitude = 27.770787,
form_values = new Dictionary<string, string>();
}
}
data.record.form_values["833b"] = "99999";
data.record.form_values["683b"] = "9999999";
data.record.form_values["fa37"] = "Testing";
data.record.form_values["b2e3"] = "Testing";
Then get the JSON:
string json = JsonConvert.SerializeObject(data);
I think it is much similar to this One. you can try the following code to achhieve the requirement:
var dd = {
"FirstName": "ABC",
"username": "abc123",
"password": "abc#123",
"Cnumbers": [{
"Home": "0987654321"
}, {
"Company": "7654321"
}]
}

How do I get formatted JSON in .NET using C#?

I am using .NET JSON parser and would like to serialize my config file so it is readable. So instead of:
{"blah":"v", "blah2":"v2"}
I would like something nicer like:
{
"blah":"v",
"blah2":"v2"
}
My code is something like this:
using System.Web.Script.Serialization;
var ser = new JavaScriptSerializer();
configSz = ser.Serialize(config);
using (var f = (TextWriter)File.CreateText(configFn))
{
f.WriteLine(configSz);
f.Close();
}
You are going to have a hard time accomplishing this with JavaScriptSerializer.
Try JSON.Net.
With minor modifications from JSON.Net example
using System;
using Newtonsoft.Json;
namespace JsonPrettyPrint
{
internal class Program
{
private static void Main(string[] args)
{
Product product = new Product
{
Name = "Apple",
Expiry = new DateTime(2008, 12, 28),
Price = 3.99M,
Sizes = new[] { "Small", "Medium", "Large" }
};
string json = JsonConvert.SerializeObject(product, Formatting.Indented);
Console.WriteLine(json);
Product deserializedProduct = JsonConvert.DeserializeObject<Product>(json);
}
}
internal class Product
{
public String[] Sizes { get; set; }
public decimal Price { get; set; }
public DateTime Expiry { get; set; }
public string Name { get; set; }
}
}
Results
{
"Sizes": [
"Small",
"Medium",
"Large"
],
"Price": 3.99,
"Expiry": "\/Date(1230447600000-0700)\/",
"Name": "Apple"
}
Documentation: Serialize an Object
A shorter sample code for Json.Net library
private static string FormatJson(string json)
{
dynamic parsedJson = JsonConvert.DeserializeObject(json);
return JsonConvert.SerializeObject(parsedJson, Formatting.Indented);
}
If you have a JSON string and want to "prettify" it, but don't want to serialise it to and from a known C# type then the following does the trick (using JSON.NET):
using System;
using System.IO;
using Newtonsoft.Json;
class JsonUtil
{
public static string JsonPrettify(string json)
{
using (var stringReader = new StringReader(json))
using (var stringWriter = new StringWriter())
{
var jsonReader = new JsonTextReader(stringReader);
var jsonWriter = new JsonTextWriter(stringWriter) { Formatting = Formatting.Indented };
jsonWriter.WriteToken(jsonReader);
return stringWriter.ToString();
}
}
}
Shortest version to prettify existing JSON: (edit: using JSON.net)
JToken.Parse("mystring").ToString()
Input:
{"menu": { "id": "file", "value": "File", "popup": { "menuitem": [ {"value": "New", "onclick": "CreateNewDoc()"}, {"value": "Open", "onclick": "OpenDoc()"}, {"value": "Close", "onclick": "CloseDoc()"} ] } }}
Output:
{
"menu": {
"id": "file",
"value": "File",
"popup": {
"menuitem": [
{
"value": "New",
"onclick": "CreateNewDoc()"
},
{
"value": "Open",
"onclick": "OpenDoc()"
},
{
"value": "Close",
"onclick": "CloseDoc()"
}
]
}
}
}
To pretty-print an object:
JToken.FromObject(myObject).ToString()
Oneliner using Newtonsoft.Json.Linq:
string prettyJson = JToken.Parse(uglyJsonString).ToString(Formatting.Indented);
Net Core App
var js = JsonSerializer.Serialize(obj, new JsonSerializerOptions {
WriteIndented = true
});
All this can be done in one simple line:
string jsonString = JsonConvert.SerializeObject(yourObject, Formatting.Indented);
Here is a solution using Microsoft's System.Text.Json library:
static string FormatJsonText(string jsonString)
{
using var doc = JsonDocument.Parse(
jsonString,
new JsonDocumentOptions
{
AllowTrailingCommas = true
}
);
MemoryStream memoryStream = new MemoryStream();
using (
var utf8JsonWriter = new Utf8JsonWriter(
memoryStream,
new JsonWriterOptions
{
Indented = true
}
)
)
{
doc.WriteTo(utf8JsonWriter);
}
return new System.Text.UTF8Encoding()
.GetString(memoryStream.ToArray());
}
You may use following standard method for getting formatted Json
JsonReaderWriterFactory.CreateJsonWriter(Stream stream, Encoding encoding, bool ownsStream, bool indent, string indentChars)
Only set "indent==true"
Try something like this
public readonly DataContractJsonSerializerSettings Settings =
new DataContractJsonSerializerSettings
{ UseSimpleDictionaryFormat = true };
public void Keep<TValue>(TValue item, string path)
{
try
{
using (var stream = File.Open(path, FileMode.Create))
{
//var currentCulture = Thread.CurrentThread.CurrentCulture;
//Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
try
{
using (var writer = JsonReaderWriterFactory.CreateJsonWriter(
stream, Encoding.UTF8, true, true, " "))
{
var serializer = new DataContractJsonSerializer(type, Settings);
serializer.WriteObject(writer, item);
writer.Flush();
}
}
catch (Exception exception)
{
Debug.WriteLine(exception.ToString());
}
finally
{
//Thread.CurrentThread.CurrentCulture = currentCulture;
}
}
}
catch (Exception exception)
{
Debug.WriteLine(exception.ToString());
}
}
Pay your attention to lines
var currentCulture = Thread.CurrentThread.CurrentCulture;
Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
....
Thread.CurrentThread.CurrentCulture = currentCulture;
For some kinds of xml-serializers you should use InvariantCulture to avoid exception during deserialization on the computers with different Regional settings. For example, invalid format of double or DateTime sometimes cause them.
For deserializing
public TValue Revive<TValue>(string path, params object[] constructorArgs)
{
try
{
using (var stream = File.OpenRead(path))
{
//var currentCulture = Thread.CurrentThread.CurrentCulture;
//Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
try
{
var serializer = new DataContractJsonSerializer(type, Settings);
var item = (TValue) serializer.ReadObject(stream);
if (Equals(item, null)) throw new Exception();
return item;
}
catch (Exception exception)
{
Debug.WriteLine(exception.ToString());
return (TValue) Activator.CreateInstance(type, constructorArgs);
}
finally
{
//Thread.CurrentThread.CurrentCulture = currentCulture;
}
}
}
catch
{
return (TValue) Activator.CreateInstance(typeof (TValue), constructorArgs);
}
}
Thanks!
Using System.Text.Json set JsonSerializerOptions.WriteIndented = true:
JsonSerializerOptions options = new JsonSerializerOptions { WriteIndented = true };
string json = JsonSerializer.Serialize<Type>(object, options);
2023 Update
For those who ask how I get formatted JSON in .NET using C# and want to see how to use it right away and one-line lovers. Here are the indented JSON string one-line codes:
There are 2 well-known JSON formatter or parsers to serialize:
Newtonsoft Json.Net version:
using Newtonsoft.Json;
var jsonString = JsonConvert.SerializeObject(yourObj, Formatting.Indented);
.Net 7 version:
using System.Text.Json;
var jsonString = JsonSerializer.Serialize(yourObj, new JsonSerializerOptions { WriteIndented = true });
using System.Text.Json;
...
var parsedJson = JsonSerializer.Deserialize<ExpandoObject>(json);
var options = new JsonSerializerOptions() { WriteIndented = true };
return JsonSerializer.Serialize(parsedJson, options);
First I wanted to add comment under Duncan Smart post, but unfortunately I have not got enough reputation yet to leave comments. So I will try it here.
I just want to warn about side effects.
JsonTextReader internally parses json into typed JTokens and then serialises them back.
For example if your original JSON was
{ "double":0.00002, "date":"\/Date(1198908717056)\/"}
After prettify you get
{
"double":2E-05,
"date": "2007-12-29T06:11:57.056Z"
}
Of course both json string are equivalent and will deserialize to structurally equal objects, but if you need to preserve original string values, you need to take this into concideration
I have something very simple for this. You can put as input really any object to be converted into json with a format:
private static string GetJson<T> (T json)
{
return JsonConvert.SerializeObject(json, Formatting.Indented);
}
This worked for me. In case someone is looking for a VB.NET version.
#imports System
#imports System.IO
#imports Newtonsoft.Json
Public Shared Function JsonPrettify(ByVal json As String) As String
Using stringReader = New StringReader(json)
Using stringWriter = New StringWriter()
Dim jsonReader = New JsonTextReader(stringReader)
Dim jsonWriter = New JsonTextWriter(stringWriter) With {
.Formatting = Formatting.Indented
}
jsonWriter.WriteToken(jsonReader)
Return stringWriter.ToString()
End Using
End Using
End Function
.NET 5 has built in classes for handling JSON parsing, serialization, deserialization under System.Text.Json namespace. Below is an example of a serializer which converts a .NET object to a JSON string,
using System.Text.Json;
using System.Text.Json.Serialization;
private string ConvertJsonString(object obj)
{
JsonSerializerOptions options = new JsonSerializerOptions();
options.WriteIndented = true; //Pretty print using indent, white space, new line, etc.
options.NumberHandling = JsonNumberHandling.AllowNamedFloatingPointLiterals; //Allow NANs
string jsonString = JsonSerializer.Serialize(obj, options);
return jsonString;
}
Below code works for me:
JsonConvert.SerializeObject(JToken.Parse(yourobj.ToString()))
For UTF8 encoded JSON file using .NET Core 3.1, I was finally able to use JsonDocument based upon this information from Microsoft: https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-how-to#utf8jsonreader-utf8jsonwriter-and-jsondocument
string allLinesAsOneString = string.Empty;
string [] lines = File.ReadAllLines(filename, Encoding.UTF8);
foreach(var line in lines)
allLinesAsOneString += line;
JsonDocument jd = JsonDocument.Parse(Encoding.UTF8.GetBytes(allLinesAsOneString));
var writer = new Utf8JsonWriter(Console.OpenStandardOutput(), new JsonWriterOptions
{
Indented = true
});
JsonElement root = jd.RootElement;
if( root.ValueKind == JsonValueKind.Object )
{
writer.WriteStartObject();
}
foreach (var jp in root.EnumerateObject())
jp.WriteTo(writer);
writer.WriteEndObject();
writer.Flush();

Categories