A third party API is returning JSON in the following format
{
"group1": {
"Colour": "Blue",
"Name": "Dave"
},
"group2": {
"Colour": "Red",
"Name": "Karen"
},
"group3": {
"Colour": "Green",
"Name": "Ryan"
}
}
I'm finding the outer 'groupX' identifier to problematic when attempting to deserialize the JSON using JSON.NET.
Does anyone know best to parse JSON in this format?
{
"employees": [
{ "first-name":"John" , "last-name":"Doe" },
{ "first-name":"Anna" , "last-name":"Smith" },
{ "first-name":"Peter" , "last-name":"Jones" }
]
}
Your JSON is Correct.
if tou want to check than use below url JSONlint
Define a class Group like this:
class Group
{
public string Colour { get; set; }
public string Name { get; set; }
}
Then you can deserialize like this:
var dict = JsonConvert.DeserializeObject<Dictionary<string, Group>>(json);
Here's a quick demo:
string json = #"
{
""group1"": {
""Colour"": ""Blue"",
""Name"": ""Dave""
},
""group2"": {
""Colour"": ""Red"",
""Name"": ""Karen""
},
""group3"": {
""Colour"": ""Green"",
""Name"": ""Ryan""
}
}";
var dict = JsonConvert.DeserializeObject<Dictionary<string, Group>>(json);
foreach (var kvp in dict)
{
Console.WriteLine(kvp.Key);
Group group = kvp.Value;
Console.WriteLine(" Colour: " + group.Colour);
Console.WriteLine(" Name: " + group.Name);
}
Output:
group1
Colour: Blue
Name: Dave
group2
Colour: Red
Name: Karen
group3
Colour: Green
Name: Ryan
Related
I'm trying to add data to elastic search. When I'm pushing the IDictionary<string,object> type properties to Elasticsearch it stores the data in a different way and returns me different result.
Model
using Nest;
namespace FrontLine.Db.Elasticsearch.Models
{
[ElasticsearchType(RelationName = "event")]
public class Event
{
public DateTime TimeStamp { get; set; }
[Text(Name = "event_name")]
public string EventName { get; set; } = null!;
[Object]
public IDictionary<string,object> Properties { get; set; } = null!;
}
}
Data that I'm saving
[
{
"timeStamp": "2022-06-14T20:33:14.866Z",
"eventName": "hello1",
"properties": {
"additionalProp1": "string",
"additionalProp2": "string",
"additionalProp3": "string"
}
}
]
Result I'm getting from Elasticsearch
[
{
"timeStamp": "2022-06-14T20:33:14.866Z",
"eventName": "hello1",
"properties": {
"additionalProp1": {
"valueKind": 3
},
"additionalProp2": {
"valueKind": 3
},
"additionalProp3": {
"valueKind": 3
}
}
}
]
What should I change in or how should I map it to get the correct data form elastic search?
I'm having this request body for Google DLP as a text value. Is there any way to configure userdefined RedactConfig to modify the output..?. Is there any way to achieve that one..?
{
"item":{
"value":"My name is Alicia Abernathy, and my email address is aabernathy#example.com."
},
"deidentifyConfig":{
"infoTypeTransformations":{
"transformations":[
{
"infoTypes":[
{
"name":"EMAIL_ADDRESS"
}
],
"primitiveTransformation":{
"replaceWithInfoTypeConfig":{
}
}
}
]
}
},
"inspectConfig":{
"infoTypes":[
{
"name":"EMAIL_ADDRESS"
}
]
}
}
Is there any way to configure userdefined RedactConfig to modify the output..?
And I need the following O/P from Google DLP.
{
"item": {
"value": "My name is Alicia Abernathy, and my email address is {{__aabernathy#example.com__[EMAIL_ADDRESS]__}}."
},
"overview": {
"transformedBytes": "22",
"transformationSummaries": [
{
"infoType": {
"name": "EMAIL_ADDRESS"
},
"transformation": {
"replaceWithInfoTypeConfig": {}
},
"results": [
{
"count": "1",
"code": "SUCCESS"
}
],
"transformedBytes": "22"
}
]
}
}
So you don't actually want to anonymize text, you just want to add information to it? This API isn't suitable for that ... your best bet is to just use inspectContent and with the byte offsets in the findings do your own transforms.
Something like this in pseudocode ...
private static final void labelStringWithFindings(
String stringToLabel,
InspectContentResponse dlpResponse) {
StringBuilder output = new StringBuilder();
final byte[] messageBytes = ByteString.copyFromUtf8(
stringToLabel).toByteArray();
ImmutableList sortedFindings =
sort(dlpResponse.getResult().getFindingsList());
int lastEnd = 0;
for (Finding finding : sortedFindings) {
String quote = Ascii.toLowerCase(finding.getQuote());
String infoType = finding.getInfoType().getName();
String surrogate = String.format("{{__%s__[%s]__}}",
quote, infoType);
final byte[] surrogateBytes = surrogate.getBytes(StandardCharsets.UTF_8);
int startIndex = (int) finding.getLocation().getByteRange().getStart();
int endIndex = (int) finding.getLocation().getByteRange().getEnd();
if (lastEnd == 0 || startIndex > lastEnd) {
output.write(messageBytes, lastEnd, startIndex - lastEnd);
output.write(surrogateBytes, 0, surrogate.length);
}
if (endIndex > lastEnd) {
lastEnd = endIndex;
}
}
if (messageBytes.length > lastEnd) {
output.write(messageBytes, lastEnd, messageBytes.length - lastEnd);
}
return output.toString();
}
Let me try to simplify my question by extracting and abstracting relevant information from a complex object and large JSON text.
Class Foo()
{
string Name;
Version[] versions;
}
JsonText(converted from XML) can be something like this:
"Foo": {
"Name": "test",
"versions": {
"Major": "1",
"Minor": "1"
},
"versions": {
"Major": "2",
"Minor": "1"
},
"versions": {
"Major": "3",
"Minor": "1"
}
}
or the following:
"Foo": {
"Name": "test",
"versions": {
"Major": "1",
"Minor": "1"
}
}
JsonConvert.DeserializeObject(JsonText) results in:
Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'Version[]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
Is it possible to do this desrialization?
Updated based on commment
Your Json doesn't look valid. A Json needs to be enclosed with "[" "]". For example,
[ "Ford", "BMW", "Fiat" ]
If you are allowed to modify your Json, You could modify the Json as following
{
"Foo":
{
"Name": "test",
"versions": [
{
"Major": "1",
"Minor": "1"
},
{
"Major": "2",
"Minor": "1"
},
{
"Major": "3",
"Minor": "1"
}]
}
}
Based on your comment, you would like to avoid the Json Array Syntax if there is only a single element. On other cases, you would like to stick to Array Syntax. In such scenario,you could write a Custom Json Converter.
class CustomConverter<T> : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return (objectType == typeof(List<T>));
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JToken token = JToken.Load(reader);
if (token.Type == JTokenType.Array)
{
return token.ToObject<List<T>>().ToArray();
}
return new List<T> { token.ToObject<T>() }.ToArray();
}
public override bool CanWrite
{
get { return false; }
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
You can decorate your class with JsonConverter attribute to use the Custom Json Converter.
class Wrapper
{
public Foo Foo{get;set;}
}
class Foo
{
[JsonProperty("Name")]
public string Name{get;set;}
[JsonProperty("versions")]
[JsonConverter(typeof(CustomConverter<Version>))]
public Version[] versions{get;set;}
}
Now you can deserialize as
var result =JsonConvert.DeserializeObject<Wrapper>(str);
This would now work, if you use either of following Json definition.
{
'Foo':
{
'Name': 'test',
'versions': [
{
'Major': '1',
'Minor': '1'
},
{
'Major': '2',
'Minor': '1'
},
{
'Major': '3',
'Minor': '1'
}]
}
}
Single Version (Without Array syntax)
{
'Foo':
{
'Name': 'test',
'versions':
{
'Major': '1',
'Minor': '1'
}
}
}
I need to have a json with this format:
var projects = [
{ Title: 'Dave Jones', city: 'Phoenix' },
{ Title: 'Jamie Riley', city: 'Atlanta' },
{ Title: 'Heedy Wahlin', city: 'Chandler' },
{ Title: 'Thomas Winter', city: 'Seattle' }
];
in web method I serialized list of objects this way:
[WebMethod]
public string GetUserProfileProjects()
{
List<Test> data = new List<Test>() {
new Test{ Title= "Dave Jones", City= "Phoenix" },
new Test{ Title= "Jamie Riley", City = "Atlanta" },
new Test{ Title= "Heedy Wahlin", City= "Chandler" },
new Test{ Title= "Thomas Winter", City= "Seattle" }
};
JavaScriptSerializer serializer = new JavaScriptSerializer();
return serializer.Serialize(data);
}
public class Test
{
public string Title { get; set; }
public string City { get; set; }
}
but the json result in ajax call is in this format:
why each item is hooked to an Object ?
You would want to serialize a IEnumerable<Dictionary<string,string>> to get the desired result.
Test is an object, therefore, each entry is hooked up to that particular object.
As long as you continue to use List<Test> your JSON result will be the same.
hello I have a problem to deserialize this json
{
"166": {
"uid": "166",
"name": "test",
"mail": "test#test.com"
},
"167": {
"uid": "167",
"name": "test",
"mail": "test#test.com"
},
"168": {
"uid": "168",
"name": "test",
"mail": "test#test.com"
}
}
I use json.net and would retrieve all users, but the first element is always changing its name.
Any idea how to treat it?
You can handle this situation by deserializing into a Dictionary<string, User>, assuming you have a User class defined like this:
public class User
{
public string uid { get; set; }
public string name { get; set; }
public string mail { get; set; }
}
Here is a demo:
class Program
{
static void Main(string[] args)
{
string json = #"
{
""166"": {
""uid"": ""166"",
""name"": ""Joe"",
""mail"": ""joe#example.org""
},
""167"": {
""uid"": ""167"",
""name"": ""Pete"",
""mail"": ""pete#example.org""
},
""168"": {
""uid"": ""168"",
""name"": ""Fred"",
""mail"": ""fred#example.org""
}
}";
Dictionary<string, User> users =
JsonConvert.DeserializeObject<Dictionary<string, User>>(json);
foreach (KeyValuePair<string, User> kvp in users)
{
Console.WriteLine(kvp.Key);
Console.WriteLine(" uid: " + kvp.Value.uid);
Console.WriteLine(" name: " + kvp.Value.name);
Console.WriteLine(" mail: " + kvp.Value.mail);
}
}
}
Here is the output:
166
uid: 166
name: Joe
mail: joe#example.org
167
uid: 167
name: Pete
mail: pete#example.org
168
uid: 168
name: Fred
mail: fred#example.org