I am trying to convert my json data to c sharp understandable format so that I can use JsonConvert.SerializeObject to convert that data to JSON format and send it over HTTP protocol. My json data is as follows:
{
"m2m:ae":
{
"api": "ADN_AE_ATCARD06",
"rr": "true",
"lbl": ["AT06"],
"rn": " adn-ae_AT06"
}
}
I tried to write it in c sharp understandable format but was able to do this:
var obj = new
{
m2m = new
{
api = "ADN_AE45",
rr = "true",
lbl = new[] { "ad" },
rn = "adfrt"
}
};
var result = JsonConvert.SerializeObject(obj, Formatting.Indented);
my issue is how to include m2m:ae into my c-sharp code. I am new to json, I am able to convert only if parent object has no value but if it has value I am not able to. please help.
I was incorrect in my comment. While "m2m:ae" is not a valid name for a C# property is valid JSON. This can be accomplished by tagging the class property with JsonProperty.
Define your class like this
public class TestJson
{
[JsonProperty("m2m:ae")]
public Class2 Class2Instance { get; set; }
}
public class Class2
{
public string Api { get; set; }
public string Rr { get; set; }
public string[] Lbl { get; set; }
public string Rn { get; set; }
}
and then populate your class like this
_sut = new TestJson
{
Class2Instance = new Class2 {Api = "ADN_AE45", Rr = "true", Lbl = new[] {"ad"}, Rn = "adfrt"}
};
and serialize
_result = JsonConvert.SerializeObject(_sut, new JsonSerializerSettings
{
ContractResolver = new CamelCasePropertyNamesContractResolver()
});
The resulting serialized object looks like
{
"m2m:ae": {
"api": "ADN_AE45",
"rr": "true",
"lbl": ["ad"],
"rn": "adfrt"
}
}
and deserialization is the reverse
var test = JsonConvert.DeserializeObject<TestJson>(_result, new JsonSerializerSettings
{
ContractResolver = new CamelCasePropertyNamesContractResolver()
});
Did you write the Json in a text file?
If yeah so fileTxt is what is written on the file(as json)
String fileTxt = File.ReadAllText(Give a path for a file); //read from file
Jobject Json = Jobject.Parse(fileTxt); //convert the string to Json
Console.WriteLine($"rr: {Json["rr"]} "); // get the rr from json and print it
Other than class method mentioned by Fran one can use the Dictionary method to create key value pair and newtonsoft.json library to convert to json.
var sub= Dictionary<string,string>
{{"abc","xyz"}
};
var main = Dictionary<string,object>
{{"wer:asd",sub}
};
string str= JsonConvert.SerializeObject(main);
Related
How to serialize an object to json through setting json field name from object's property value?
I am using NewtonsoftJson as a json library.
public class Data
{
public string Question {get;set;} = "Test Question?";
public string Answer {get;set;} = "5";
}
expected json output:
{
"Test Question?": {
"Answer": "5"
}
}
You can use a dictionary for that:
JsonSerializer.Serialize(
new Dictionary<string, object>
{
{
data.Question, new
{
data.Answer
}
}
});
or if you are using Newtonsoft, you can use the
JsonConvert.SerializeObject method for serialization, with the same input.
Just for a record
var data = new Data();
string json = new JObject { [data.Question] = new JObject { ["Answer"] = data.Answer } }.ToString();
I've written some code which has to read through 5,000 JSON files and replace a number which appears twice in each file. It's set to create a new json file and delete the old one, with that, other data must be transferred into the new file too, which is not a problem, however we have a list called attributes that contain some text that use single quotes (for punctuation.) - however when the new json file is written, the text with the single quotes is changed and the single quote is replaced with \u0027
Example: old file contains:"0.png" and "Hen's Secret Bra" which in the new file is changing to "5000.png" correct, and "Hen\u0027s Secret Bra" incorrect. How do I transfer the single quote over properly?
Here is my code:
using System.Text.Json;
using System.Web;
internal class Program
{
private static void Main(string[] args)
{
//get all the json files
var jsonPath = #"/Users/jasonnienaber/Desktop/nft/cef/official/fatJSONselfFIX/test";
var jsonFiles = Directory.GetFiles(jsonPath, "*.json");
//loop through each file and process according to specs
foreach(var jsonFile in jsonFiles)
{
var json = File.ReadAllText(jsonFile);
var sample = JsonSerializer.Deserialize<Sample>(json);
var sampleNew = new SampleNew();
var intCounter = 0;
var newIntCounter = intCounter+5000;
var Counter = intCounter.ToString();
var newCounter = newIntCounter.ToString();
sampleNew.image = sample.image.Replace(Counter, newCounter);
sampleNew.name = sample.name.Replace(Counter, newCounter);
sampleNew.description = sample.description;
sampleNew.external_url = sample.external_url;
sampleNew.attributes = sample.attributes;
// serialize JSON to a string and then write string to a file
File.Delete(jsonFile);
File.WriteAllText(jsonFile, JsonSerializer.Serialize(sampleNew));
intCounter++;
}
}
public class Attribute
{
public string trait_type { get; set; }
public string value { get; set; }
}
public class Sample
{
// public string dna { get; set; }
public string image { get; set; }
public string name { get; set; }
public string description { get; set; }
public string external_url { get; set; }
public List<Attribute> attributes { get; set; }
public string compiler { get; set; }
}
public class SampleNew
{
public string image { get; set; }
public string name { get; set; }
public string description { get; set; }
public string external_url { get; set; }
//public List<Attribute> attributes { get; set; }
public List<Attribute> attributes {get; set;}
}
}
The "Hen's Secret Bra" is within attributes
Like Jon Skeet mentioned, it's valid to use \u0027, however, you can change the serializer encoding options:
using System.Text.Json;
var obj = new
{
Name = "John's awesome object",
Age = 31
};
var options = new JsonSerializerOptions
{
Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping
};
// writes obj to json file
File.WriteAllText("obj.json", JsonSerializer.Serialize(obj, options));
Outputs
{"Name":"John's awesome object","Age":31}
So in your code, you can do as follows:
var options = new JsonSerializerOptions
{
Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping
};
//loop through each file and process according to specs
foreach (var jsonFile in jsonFiles)
{
var json = File.ReadAllText(jsonFile);
var sample = JsonSerializer.Deserialize<Sample>(json);
var sampleNew = new SampleNew();
var intCounter = 0;
var newIntCounter = intCounter + 5000;
var Counter = intCounter.ToString();
var newCounter = newIntCounter.ToString();
sampleNew.image = sample.image.Replace(Counter, newCounter);
sampleNew.name = sample.name.Replace(Counter, newCounter);
sampleNew.description = sample.description;
sampleNew.external_url = sample.external_url;
sampleNew.attributes = sample.attributes;
// serialize JSON to a string and then write string to a file
File.Delete(jsonFile);
// use serializer options
File.WriteAllText(jsonFile, JsonSerializer.Serialize(sampleNew, options));
intCounter++;
}
See UnsafeRelaxedJsonEscaping
It is better to use Newtonsoft.Json to avoid any problems like this one.
But one of the thing you can try to fix an issue is to use a serialize options
var options = new JsonSerializerOptions
{
Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping
};
but it is unsafe
Another option is more awkward but more safe, since it affects only one symbol, not any as in the first case
var attr= new Attribute{trait_type="trait_type", value="Hen's Secret Bra"};
attr.value=attr.value.Replace("'","==="); //or you can try something else if you don't like ===
var json=System.Text.Json.JsonSerializer.Serialize(attr);
json=json.Replace("===","'");
File.WriteAllText(jsonFile, json);
json = File.ReadAllText(jsonFile);
result
{"trait_type":"trait_type","value":"Hen's Secret Bra"}
I am doing a bot for VK on C# and faced to some problems. I have method which returns JSON like this
{
"ts": 1674111105,
"updates": [[4,
2262,
17,
61835649,
1534493714,
"",
{
"attach1_type": "doc",
"attach1": "61835649_472186415",
"title": " ... "
}
]]
}
This is object, as I see, but I cant get anything from the attach_type1 to title including. This is also an object, and it can't be transformed to string just like .ToString(), because in that case in the result I have System.Object. So, does anybody know how I can change this type or is it impossible?? I am in desperation.
I created a class for this object
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.Serialization;
namespace CSharpVKbot.VK.UserLongPoll
{
[DataContract()]
public class Attachment
{
[DataMember(Name = "attach1_type")]
public string AttachType;
[DataMember(Name = "attach1")]
public string Attach;
[DataMember(Name = "title")]
public string Title;
}
}
created an object of this class
public Attachment DocId = new Attachment();
and then tried to change type to attachment, but it doesnt work either
case UpdateCode.NewMessage:
u.MessageID = (int)item[1];
u.Flags = (int)item[2];
u.PeerID = (int)item[3];
u.TimeStamp = (int)item[4];
u.Text = (string)item[5];
u.DocId = (Attachment)item[6];
break;
You need to deserialise the JSON - It cannot be just converted to an object.
Try something like
Attachment deserializedAttachement = new Attachment();
MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(item[6]));
DataContractJsonSerializer ser = new DataContractJsonSerializer(deserializedAttachment.GetType());
deserializedAttachment = ser.ReadObject(ms) as Attachment;
ms.Close();
Where item[6] is the string that represents the attachment information.
See - https://learn.microsoft.com/en-us/dotnet/framework/wcf/feature-details/how-to-serialize-and-deserialize-json-data#example
I think that you will have to iterate through all json properties.
This code may help you
dynamic obj = Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(YourJsonString);
foreach (var prop in obj)
{
if (prop is Newtonsoft.Json.Linq.JObject)
{
// Handle JObject
}
if (prop is Newtonsoft.Json.Linq.JProperty)
{
// Handle JProperty
}
}
There are many direction to resolve your problem.
I like it (using Newtonsoft):
JObject data = (JObject)JsonConvert.DeserializeObject(json);
var attach1_type = data.Descendants()
.OfType<JProperty>()
.FirstOrDefault(x => x.Name == "attach1_type")
?.Value;
numbers, strings, objects are in same array, which means they are boxed before returning to you. so your updates is List<List<object>> or object[][], whatever. your c# class, which match this json format, could be simply like this:
public class SomethingJsonResult
{
public int ts { get; set; }
public List<List<object>> updates { get; set; }
}
The 1st option is to use anonymous type:
public void ParseJsonResult(SomethingJsonResult result)
{
var definition = new
{
attach1_type = "",
attach1 = "",
title = ""
};
result?.updates?.ForEach(x =>
{
var update = JsonConvert.DeserializeAnonymousType(x[6], definition);
var attachment = new Attachment
{
AttachType = update.attach1_type,
Attach = update.attach1,
Title = update.title,
};
});
}
The 2nd option is a bit complex:
[DataContract()]
public class Attachment
{
[DataMember(Name = "attach1_type")]
[JsonProperty("attach1_type")] //Tell JsonConverter how to map your object
public string AttachType { get; set; }//Here is property, but not variable
[DataMember(Name = "attach1")]
[JsonProperty("attach1")]
public string Attach { get; set; }
[DataMember(Name = "title")]
[JsonProperty("title")]
public string Title { get; set; }
}
public void ParseJsonResult(SomethingJsonResult result)
{
result?.updates?.ForEach(update =>
{
//(Attachment)update[6] works only when your names of properties 100% match json objects
JsonConvert.DeserializeObject<Attachment>(update[6])
....
});
}
DataContractSerializer example:
https://learn.microsoft.com/en-us/dotnet/api/system.runtime.serialization.datamemberattribute?redirectedfrom=MSDN&view=netframework-4.7.2
you can implement everything inside your custom converter:
https://www.newtonsoft.com/json/help/html/CustomJsonConverter.htm
JsonConvert.DeserializeObject<AttachmentWrapper>(json, new AttachmentConverter(typeof(AttachmentWrapper)));
I have to read a JSON stream (which I have no control over), which is in the form:
{"files":
{
"/some_file_path.ext": {"size":"1000", "data":"xxx", "data2":"yyy"},
"/other_file_path.ext": {"size":"2000", "data":"xxx", "data2":"yyy"},
"/another_file_path.ext": {"size":"3000", "data":"xxx", "data2":"yyy"},
}
}
So, I have an object named files, which has a number of properties, which have 1) different names every time, 2) different number of them every time, and 3) names with characters which can't be used in C# properties.
How do I deserialize this?
I'm putting this into a Portable Library, so I can't use the JavaScriptSerializer, in System.Web.Script.Serialization, and I'm not sure about JSON.NET. I was hoping to use the standard DataContractJsonSerializer.
UPDATE: I've changed the sample data to be closer to the actual data, and corrected the JSON syntax in the area the wasn't important. (Still simplified quite a bit, but the other parts are fairly standard)
You can model your "files" object as a Dictionary keyed by the JSON property name:
public class RootObject
{
public Dictionary<string, PathData> files { get; set; }
}
public class PathData
{
public int size { get; set; }
public string data { get; set; }
public string data2 { get; set; }
}
Then, only if you are using .Net 4.5 or later, you can deserialize using DataContractJsonSerializer, but you must first set DataContractJsonSerializerSettings.UseSimpleDictionaryFormat = true:
var settings = new DataContractJsonSerializerSettings { UseSimpleDictionaryFormat = true };
var root = DataContractJsonSerializerHelper.GetObject<RootObject>(jsonString, settings);
With the helper method:
public static class DataContractJsonSerializerHelper
{
public static T GetObject<T>(string json, DataContractJsonSerializer serializer = null)
{
using (var stream = GenerateStreamFromString(json))
{
var obj = (serializer ?? new DataContractJsonSerializer(typeof(T))).ReadObject(stream);
return (T)obj;
}
}
public static T GetObject<T>(string json, DataContractJsonSerializerSettings settings)
{
return GetObject<T>(json, new DataContractJsonSerializer(typeof(T), settings));
}
private static MemoryStream GenerateStreamFromString(string value)
{
return new MemoryStream(Encoding.Unicode.GetBytes(value ?? ""));
}
}
Alternatively, you can install Json.NET and do:
var root = JsonConvert.DeserializeObject<RootObject>(jsonString);
Json.NET automatically serializes dictionaries to JSON objects without needing to change settings.
We need to first convert this Invalid JSON to a Valid JSON. So a Valid JSON should look like this
{
"files":
{
"FilePath" : "C:\\some\\file\\path",
"FileData" : {
"size": 1000,
"data": "xxx",
"data2": "yyy"
},
"FilePath" :"C:\\other\\file\\path",
"FileData" : {
"size": 2000,
"data": "xxx",
"data2": "yyy"
},
"FilePath" :"C:\\another\\file\\path",
"FileData" : {
"size": 3000,
"data": "xxx",
"data2": "yyy"
}
}
}
To make it a valid JSON we might use some string functions to make it looks like above. Such as
MyJSON = MyJSON.Replace("\\", "\\\\");
MyJSON = MyJSON.Replace("files", "\"files\"");
MyJSON = MyJSON.Replace("data:", "\"data:\"");
MyJSON = MyJSON.Replace("data2", "\"data2\"");
MyJSON = MyJSON.Replace(": {size", ",\"FileData\" : {\"size\"");
MyJSON = MyJSON.Replace("C:", "\"FilePath\" :\"C:");
Than we can create a class like below to read the
public class FileData
{
public int size { get; set; }
public string data { get; set; }
public string data2 { get; set; }
}
public class Files
{
public string FilePath { get; set; }
public FileData FileData { get; set; }
}
public class RootObject
{
public Files files { get; set; }
}
Assuming you have a valid JSON you could use JavaScriptSerializer to return a list of objects
string json = "{}"
var serializer = new JavaScriptSerializer();
var deserializedValues = (Dictionary<string, object>)serializer.Deserialize(json, typeof(object));
Alternatively you could specify Dictionary<string, List<string>> as the type argument
strign json = "{}";
JavaScriptSerializer serializer = new JavaScriptSerializer();
var deserializedValues = serializer.Deserialize<Dictionary<string, List<string>>>(json);
foreach (KeyValuePair<string, List<string>> kvp in deserializedValues)
{
Console.WriteLine(kvp.Key + ": " + string.Join(",", kvp.Value));
}
I have a List of class objects that have email address and status data members. I am trying to convert these to a json, making sure to have the "operations" word on the array.
This is my class:
class MyClass
{
public string email {get; set; }
public string status { get; set; }
}
This is my current code (not building):
List<MyClass> data = new List<MyClass>();
data = MagicallyGetData();
string json = new {
operations = new {
JsonConvert.SerializeObject(data.Select(s => new {
email_address = s.email,
status = s.status
}))
}
};
This is the JSON I am trying to get:
{
"operations": [
{
"email_address": "email1#email.com",
"status": "good2go"
},
{
"email_address": "email2#email.com",
"status": "good2go"
},...
]
}
EDIT1
I should mention that the data I am getting for this comes from a DB. I am de-serializing a JSON from the DB and using the data in several different ways, so I cannot change the member names of my class.
I believe this will give you what you want. You will have to change your class property names if possible.
Given this class
class MyClass
{
public string email_address { get; set; }
public string status { get; set; }
}
You can add the objects to a list
List<MyClass> data = new List<MyClass>()
{
new MyClass(){email_address = "e1#it.io", status = "s1"}
, new MyClass(){ email_address = "e2#it.io", status = "s1"}
};
Using an anonymous-type you can assign data to the property operations
var json = JsonConvert.SerializeObject(new
{
operations = data
});
class MyClass
{
public string email_address { get; set; }
public string status { get; set; }
}
List<MyClass> data = new List<MyClass>() { new MyClass() { email_address = "email1#email.com", status = "good2go" }, new MyClass() { email_address = "email2#email.com", status = "good2go" } };
//Serialize
var json = JsonConvert.SerializeObject(data);
//Deserialize
var jsonToList = JsonConvert.DeserializeObject<List<MyClass>>(json);
You can try with something like this:
using System.Web.Script.Serialization;
var jsonSerialiser = new JavaScriptSerializer();
var json = jsonSerialiser.Serialize(data);
Here is the simple code
JArray.FromObject(objList);