Parse this json string to string array c# - c#

Feels like there is a one-two row solution for what I want to do:
Parse a string like this:
"{\"postalcode\":\"12345\",\"postalcity\":\"SOME-CITY\",\"country\":\"UK\",\"box\":false}"
Into something like this:
string[] result = { "12345", "SOME-CITY", "UK", "false" };
Whats the simplest way to do this?

string json = "{\"postalcode\":\"12345\",\"postalcity\":\"SOME-CITY\",\"country\":\"UK\",\"box\":false}";
var dict = new JavaScriptSerializer().Deserialize<Dictionary<string,object>>(json);
var postalCode = dict["postalcode"];
//Array is also possible
string[] result = dict.Select(kv => kv.Value.ToString()).ToArray();

You could also use newtonsoft : http://james.newtonking.com/pages/json-net.aspx
string json = #"{
""Name"": ""Apple"",
""Expiry"": new Date(1230422400000),
""Price"": 3.99,
""Sizes"": [
""Small"",
""Medium"",
""Large""
]
}";
JObject o = JObject.Parse(json);
string name = (string)o["Name"];
// Apple
JArray sizes = (JArray)o["Sizes"];
string smallest = (string)sizes[0];
// Small
I found another related post : JSON to string array in C#
Lib : http://msdn.microsoft.com/en-us/library/system.web.script.serialization.javascriptserializer.aspx

It looks like your input string is a JSON string, for which you can use a JSON deserializer if you want. If not you can use regular-expression along with named-groups as the following:
List<string> values = new List<string>();
List<string> keys= new List<string>();
string pattern = #"\""(?<key>[^\""]+)\""\:\""?(?<value>[^\"",}]+)\""?\,?";
foreach(Match m in Regex.Matches(input, pattern))
{
if (m.Success)
{
values.Add(m.Groups["value"].Value);
keys.Add(m.Groups["key"].Value);
}
}
var result = values.ToArray();
Named groups in regular-expression are indicated by (?<group-name>pattern). In the above pattern we have two named groups: key, and value which can be grabbed from the Match object using the Groups indexer.

You could use JavaScriptSerializer to serialize the json into a dynamic object which would allow you to access the properties via name e.g.
var address = new JavaScriptSerializer().Deserialize<dynamic>(json);
Console.WriteLine(address["postalcode"]);

I just ran into a similar rabbit hole. This helped me with out any other .dll installs. Hope this helps someone.
using System.Text.Json.Nodes;
public static string cSettings = AppDomain.CurrentDomain.BaseDirectory + #"\Application_Settings.json";
public static void Read_JSON()
{
string read = File.ReadAllText(cSettings);
var jsonObject = JsonNode.Parse(read);
var appname = jsonObject["appname"];
MessageBox.Show(appname.ToString());
}
//output: my test app
Application_Settings.json
{
"appname": "my test app",
"version": "1.0.003",
"id": null,
"firstrun": null,
"firstname": "t",
"lastname": "t",
"email": "some#gmail.com",
"cpu1id": "F00A20F10",
"cpu1key": null,
"gamingpc": false
}
Link to where I found this reference.
I'm using Visual Studio 2022 C#

Related

I can´t find the track and trace number in my json string

I can´t find a value in a json string using json.net
I´ve tried jsonstr[0].track_numbers[0].track_number
This is my json file.
{
"0": {
"increment_id": "112",
"track_numbers": [
{
"track_number": "2223",
"title": "tit",
"carrier_code": "custom"
}
]
},
"live_shipping_status": "Delivered"
}
I want to find the Track_nummber.
dynamic jsonstr = JsonConvert.DeserializeObject(json));
var track = jsonstr[0].track_numbers[0].track_number
(donsent work)
The 0 of your json is a string key, not an index position:
dynamic obj = JsonConvert.DeserializeObject(json);
var trackNumber = obj["0"].track_numbers[0].track_number;
Note the difference in getting the first entry of track_numbers, which is an array.

How take this json path in newtonsoft.json C#

I have been building an application where JSON will be provided from a user API. It should read the data from the JSON using JSONPath and persist the selected portions. I am trying to do this using Json.Net (Newtonsoft). The following JSON is a sample:
{
// other properties here and different structure here
"Data": [
{
"Code": "625087",
"Name": "Customer Name",
"Email": "test#hfgidfgd.com"
},
{
"Code": "625087",
"Name": "Customer Name",
"Email": "test#hfgidfgd.com"
},
{
"Code": "625087",
"Name": "Customer Name",
"Email": "test#hfgidfgd.com"
}
],
// other properties here and different structure here
}
I would like to extract the array presented by the Data property content using JSONPath and convert it to List<Dictionary<string, object>> to manipulate in my application.
In tools like jsonpath.com the following JSONPath query works fine but with Newtonsoft it does not:
// get that json
string content = GetJson();
var jo = JObject.Parse(content);
var jsonPath = "$..Data.*";
var jsonPathResult = jo.SelectTokens(jsonPath, true /* to get error when it is not found */ );
Instead I got the exception:
Property '*' not valid on JArray.
If I do the JSONPath like this:
var jsonPath = "$..Data"; // same for just: "Data"
var jsonPathResult = jo.SelectTokens(jsonPath);
I have to loop on the result with two nested foreach, what I think it is not an elegant solution:
var result = new List<Dictionary<string, object>>();
foreach (var jsonResult in jsonPathResult)
{
foreach (var item in jsonResult)
{
var fields = JsonConvert.DeserializeObject<Dictionary<string, object>>(item.ToString());
// some adjusts on the fields dictionary will be applied here...
result.Add(fields);
}
}
Is there any way to get the result to take a single loop the only the content of Data property?
As shown in JSONPath - XPath for JSON, the syntax for an array element wildcard is [*]. Thus your code should look like:
var jsonPath = "$..Data[*]";
var result = jo.SelectTokens(jsonPath, true /* to get error when it is not found */ )
.Select(o => o.ToObject<Dictionary<string, object>>())
.ToList();
Here I am using JToken.ToObject<T>() to deserialize each array element directly to a Dictionary<string, object>> without re-serializing to a string.
Sample working .Net fiddle.

Deserializing JSON response without creating a class

From the result of an API call I have a large amount of JSON to process.
I currently have this
Object convertObj = JsonConvert.DeserializeObject(responseFromServer);
I am aware that I could do something like
Movie m = JsonConvert.DeserializeObject<Movie>(responseFromServer);
And then use it like
m.FieldName
m.AnotherField
//etc
Ideally I would like to do something like
var itemName = convertObj["Name"];
to get the first Name value for the first item in the list.
Is this possible, or do I have to create a class to deserialize to?
The reason I do not want to create the class is I am not the owner of the API and the field structure may change.
Edit.
Okay so I created the class as it seems the best approach, but is there a way to deserialize the JSON into a list?
var sessionScans = new List<SessionScan>();
sessionScans = JsonConvert.DeserializeObject<SessionScan>(responseFromServer);
Complains that it cannot convert SessionScan to generic list.
No need to use dynamic, you can simply use JToken which is already does what you expect:
var json = #"
{
""someObj"": 5
}
";
var result = JsonConvert.DeserializeObject<JToken>(json);
var t = result["someObj"]; //contains 5
With .NET 6, this can be done as below,
using System.Text.Json;
using System.Text.Json.Nodes;
string jsonString = #"some json string here";
JsonNode forecastNode = JsonNode.Parse(jsonString)!;
int temperatureInt = (int)forecastNode!["Temperature"]!;
Console.WriteLine($"Value={temperatureInt}");
//for nested elements, you can access as below
int someVal = someNode!["someParent"]["childId"]!.ToString();
Refer this MS docs page for more samples - create object using initializers, make changes to DOM, deserialize subsection of a JSON payload.
You can try with JObject.Parse :
dynamic convertObj = JObject.Parse("{ 'Name': 'Jon Smith', 'Address': { 'City': 'New York', 'State': 'NY' }, 'Age': 42 }");
string name = convertObj.Name;
string address = convertObj.Address.City;
The below example can deserialize JSON to a list of anonymous objects using NewtonSoft.Json's DeserializeAnonymousType method.
var json = System.IO.File.ReadAllText(#"C:\TestJSONFiles\yourJSONFile.json");
var fooDefinition = new { FieldName = "", AnotherField = 0 }; // type with fields of string, int
var fooListDefinition = new []{ fooDefinition }.ToList();
var foos = JsonConvert.DeserializeAnonymousType(json, fooListDefinition);
You can use Json.NET's LINQ to JSON API
JObject o = JObject.Parse(jsonString);
string prop = (string)o["prop"];
Use Newtonsoft.Json
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
var json = "[{'a':'aaa','b':'bbb','c':'ccc'},{'a':'aa','b':'bb','c':'cc'}]";
var ja = (JArray)JsonConvert.DeserializeObject(json);
var jo = (JObject) ja[0];
Console.WriteLine(jo["a"]);
I had this problem working with unknown APIs then I decide to come over this problem using this approach, I'm writing down here my test case:
[TestMethod]
public void JsonDocumentDeserialize()
{
string jsonResult = #"{
""status"": ""INTERNAL_SERVER_ERROR"",
""timestamp"": ""09-09-2019 11:00:24"",
""message"": ""documentUri is required.""
}";
var jDoc = JsonDocument.Parse(jsonResult);
if (jDoc.RootElement.TryGetProperty("message", out JsonElement message))
{
Assert.IsTrue(message.GetString() == "documentUri is required.");
}
}
it worked for me because first I was looking to find a way to use dynamic type as it's mentioned in Azure Function HTTPTrigger. But I found this approach most useful and robust.
Microsoft Reference

Convert JSON String to JSON Object c#

I have this String stored in my database:
str = "{ "context_name": { "lower_bound": "value", "upper_bound": "value", "values": [ "value1", "valueN" ] } }"
This string is already in the JSON format but I want to convert it into a JObject or JSON Object.
JObject json = new JObject();
I tried the json = (JObject)str; cast but it didn't work so how can I do it?
JObject defines method Parse for this:
JObject json = JObject.Parse(str);
You might want to refer to Json.NET documentation.
if you don't want or need a typed object try:
using Newtonsoft.Json;
// ...
dynamic json = JsonConvert.DeserializeObject(str);
or try for a typed object try:
using Newtonsoft.Json;
// single
Foo foo = JsonConvert.DeserializeObject<Foo>(str);
// or as a list
List<Foo> foos = JsonConvert.DeserializeObject<List<Foo>>(str);
This works
string str = "{ 'context_name': { 'lower_bound': 'value', 'pper_bound': 'value', 'values': [ 'value1', 'valueN' ] } }";
JavaScriptSerializer j = new JavaScriptSerializer();
object a = j.Deserialize(str, typeof(object));
there's an interesting way to achive another goal which is to have a strongly type class base on json with a very powerfull tools that i used few days ago for first time to translate tradedoubler json result into classes
Is a simple tool: copy your json source paste and in few second you will have a strongly typed class json oriented .
In this manner you will use these classes which is more powerful and simply to use.
You can try like following:
string output = JsonConvert.SerializeObject(jsonStr);
This works for me using JsonConvert
var result = JsonConvert.DeserializeObject<Class>(responseString);
If your JSon string has "" double quote instead of a single quote ' and has \n as a indicator of a next line then you need to remove it because that's not a proper JSon string, example as shown below:
SomeClass dna = new SomeClass ();
string response = wc.DownloadString(url);
string strRemSlash = response.Replace("\"", "\'");
string strRemNline = strRemSlash.Replace("\n", " ");
// Time to desrialize it to convert it into an object class.
dna = JsonConvert.DeserializeObject<SomeClass>(#strRemNline);
In a situation where you are retrieving a list of objects of a certain entity from your api, your response string may look like this:
[{"id":1,"nome":"eeee","username":null,"email":null},{"id":2,"nome":"eeee","username":null,"email":null},{"id":3,"nome":"Ricardo","username":null,"email":null}]
In this situation you may want an array of Jason objects and cycle through them to populate your c# variable. I've done like so:
var httpResponse = await Http.GetAsync($"api/{entidadeSelecionada}");
List<List<string[]>> Valores = new();
if (httpResponse.IsSuccessStatusCode)
{
//totalPagesQuantity = int.Parse(httpResponse.Headers.GetValues("pagesQuantity").FirstOrDefault());
//Aqui tenho que colocar um try para o caso de ser retornado um objecto vazio
var responseString = await httpResponse.Content.ReadAsStringAsync();
JArray array = JArray.Parse(responseString);
foreach (JObject objx in array.Children<JObject>())
{
List<string[]> ls = new();
foreach (JProperty singleProp in objx.Properties())
{
if (!singleProp.Name.Contains("_xyz"))
{
string[] val = new string[2];
val[0] = singleProp.Name;
val[1] = singleProp.Value.ToString();
ls.Add(val);
}
}
Valores.Add(ls);
}
}
return Valores;
I achieved this solution by the #Andrei answer.
This does't work in case of the JObject this works for the simple json format data. I have tried my data of the below json format data to deserialize in the type but didn't get the response.
For this Json
{
"Customer": {
"id": "Shell",
"Installations": [
{
"id": "Shell.Bangalore",
"Stations": [
{
"id": "Shell.Bangalore.BTM",
"Pumps": [
{
"id": "Shell.Bangalore.BTM.pump1"
},
{
"id": "Shell.Bangalore.BTM.pump2"
},
{
"id": "Shell.Bangalore.BTM.pump3"
}
]
},
{
"id": "Shell.Bangalore.Madiwala",
"Pumps": [
{
"id": "Shell.Bangalore.Madiwala.pump4"
},
{
"id": "Shell.Bangalore.Madiwala.pump5"
}
]
}
]
}
]
}
}
string result = await resp.Content.ReadAsStringAsync();
List<ListView11> _Resp = JsonConvert.DeserializeObject<List<ListView11>>(result);
//List<ListView11> _objList = new List<ListView11>((IEnumerable<ListView11>)_Resp);
IList usll = _Resp.Select(a => a.lttsdata).ToList();
// List<ListViewClass> _objList = new List<ListViewClass>((IEnumerable<ListViewClass>)_Resp);
//IList usll = _objList.OrderBy(a=> a.ReqID).ToList();
Lv.ItemsSource = usll;

In C# how can I deserialize this json when one field might be a string or an array of strings?

I have an asp.net-mvc website and i am reading in Json string from a Database. Here is the following json in a DB. It could look like this:
{"description": "Test", "contacts": ["joe#gmail.com", "bill#yahoo.com"], "enabled": true}
or this:
{"description": "Test", "contacts": "joe#gmail.com, bill#yahoo.com", "enabled": true}
so as you can see, the contacts field is either:
a string (with items separated by commas)
an array of strings.
I want to convert to this class:
public class MyJob
{
public string description;
public string[] contacts;
public string enabled;
}
when i try to assign just to a string (changing the above to this: public string contacts;
) using the JavascriptSerializer():
var serializer = new JavaScriptSerializer();
string contacts = serializer.Deserialize<MyJob>(theAboveJsonString).contacts;
I get this error in the cases where its an array: Type 'System.String' is not supported for deserialization of an array.
what is the best way to go about deserializing this to handle the case of:
a string
an array of strings.
for the contact field. I am happy to put any conditional logic needed . .
I tried this:
var contacts = serializer.Deserialize<MyJob>(theAboveJsonString).contacts;
if (contacts is string)
{
jobInfo.contacts = contacts;
}
else
{
jobInfo.contacts = String.Join("; ", contacts );
}
but that didn't seem to fix as i am still getting the error above when its an array
try
var contacts = (new JavaScriptSerializer().DeserializeObject(theAboveJsonString) as Dictionary<string, object>)["contacts"];
if (contacts is object[])
{
jobInfo.contacts = String.Join("; ", contacts as object[]);
}
else
{
jobInfo.contacts = contacts.ToString();
}
For reference see MSDN and here.
You may be interested in some details here: JSON.net - field is either string or List<string>
If you're willing to use Json.NET, have this function:
public string[] getAsArray(JToken token)
{
if (token.HasValues)
{
return token.Select(m => string(m)).ToArray();
}
else
{
return ((string)token).Split(",").Select(s => s.Trim()).ToArray();
}
}
Then usage:
var json = "...";
JObject o = JObject.Parse(json);
string[] contacts = getAsArray(o["contacts"]);
For either JSON the result should be the same.
Try to deserialize contacts into a string array instead of a plain string:
string[] contacts = serializer.Deserialize<MyJob>(theAboveJsonString).contacts;
if the JSON variable is holding a plain string, use:
string[] contacts = serializer.Deserialize<MyJob>(theAboveJsonString).contacts.Split(',');

Categories