Convert dot notation to JSON - c#

How do i convert dot notation to json
The dot notation can have any depth
All data is current like this:
Dictionary<string, string> data = new Dictionary<string, string>
{
{"Company.Website", "Hjemmeside"},
{"Company.TextHeaderPlaceholder", "Firmanavn"},
{"Company.User.Manager.Repositories.CreateAsync.ArgumentNullException.InvalidCompanyId", "firma id fejl"},
{"BookingSettings.HelpText", "Hjælpe tekst på webshop"},
{"BookingSettings.OnGoingOrderValidation.Text", "Bestillings validering i gang"},
{"BookingSettings.OnGoingOrderValidation.Created", "Oprettet"},
{"BookingSettings.Url", "Kundelink til booking"}
};
Json result should be:
{
"Company": {
"Website": "Hjemmeside",
"TextHeaderPlaceholder": "Firmanavn",
"Users": {
"Managers": {
"Repositories": {
"CreateAsync": {
"ArgumentNullException": {
"InvalidCompanyId": "Can not create company user with out a company!"
}
}
}
}
}
},
"BookingSettings": {
"HelpText": "Hjælpe tekst på webshop",
"OnGoingOrderValidation": {
"Text": "Bestillings validering i gang",
"Created": "Oprettet"
},
"URL": "Kundelink til booking"
}
}
How do this the easy way?

I'd start by deserializing it to nested dictionaries.
public static Dictionary<string, object> DotNotationToDictionary(Dictionary<string, string> dotNotation)
{
Dictionary<string, object> root = new Dictionary<string, object>();
foreach (var dotObject in dotNotation)
{
var hierarcy = dotObject.Key.Split('.');
Dictionary<string, object> current = root;
for (int i = 0; i < hierarcy.Length; i++)
{
var key = hierarcy[i];
if (i == hierarcy.Length - 1) // Last key
{
current.Add(key, dotObject.Value);
}
else
{
if (!current.ContainsKey(key))
current.Add(key, new Dictionary<string, object>());
current = (Dictionary<string, object>) current[key];
}
}
}
return root;
}
Once that's done you can use JsonSerializer.Serialize to convert the dictionaries to JSON (JavaScriptEncoder.UnsafeRelaxedJsonEscaping needed for "æ"):
Dictionary<string, string> dotNotation = new Dictionary<string, string>
{
{"Company.Website", "Hjemmeside"},
{"Company.TextHeaderPlaceholder", "Firmanavn"},
{"Company.User.Manager.Repositories.CreateAsync.ArgumentNullException.InvalidCompanyId", "firma id fejl"},
{"BookingSettings.HelpText", "Hjælpe tekst på webshop"},
{"BookingSettings.OnGoingOrderValidation.Text", "Bestillings validering i gang"},
{"BookingSettings.OnGoingOrderValidation.Created", "Oprettet"},
{"BookingSettings.Url", "Kundelink til booking"}
};
var betterDictionary = DotNotationToDictionary(dotNotation);
var json = JsonSerializer.Serialize(betterDictionary, new JsonSerializerOptions { WriteIndented = true, Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping });
Console.WriteLine(json);
Here's a fiddle with it.
This is the output:
{
"Company": {
"Website": "Hjemmeside",
"TextHeaderPlaceholder": "Firmanavn",
"User": {
"Manager": {
"Repositories": {
"CreateAsync": {
"ArgumentNullException": {
"InvalidCompanyId": "firma id fejl"
}
}
}
}
}
},
"BookingSettings": {
"HelpText": "Hjælpe tekst på webshop",
"OnGoingOrderValidation": {
"Text": "Bestillings validering i gang",
"Created": "Oprettet"
},
"Url": "Kundelink til booking"
}
}

Related

Avoid the root element while serializing Dictionary with DataContractJsonSerializer

I have a Dictionary like this which I want to serialize in Json:
xrmParentPluginContextProperties = new Dictionary<string, string> {
{ "source", className },
{ "correlationId", executionContext.ParentContext.CorrelationId.ToString() },
{ "depth", executionContext.ParentContext.Depth.ToString() },
{ "initiatingUserId", executionContext.ParentContext.InitiatingUserId.ToString() },
{ "isInTransaction", executionContext.ParentContext.IsInTransaction.ToString() },
{ "isolationMode", executionContext.ParentContext.IsolationMode.ToString() },
{ "message", executionContext.ParentContext.MessageName },
{ "mode", getModeName(executionContext.ParentContext.Mode) },
{ "operationId", executionContext.ParentContext.OperationId.ToString() },
{ "orgId", executionContext.ParentContext.OrganizationId.ToString() },
{ "orgName", executionContext.ParentContext.OrganizationName },
{ "requestId", executionContext.ParentContext.RequestId.ToString() },
{ "userId", executionContext.ParentContext.UserId.ToString() },
{ "entityId", executionContext.ParentContext.PrimaryEntityId.ToString() },
{ "entityName", executionContext.ParentContext.PrimaryEntityName },
{ "type", "Plugin" },
{ "stage", getStageName(executionContext.Stage) }
};
Then I have a helper class holding the dictionary for serialization:
public class DictionarySerializationHelperClass
{
public Dictionary<string, string> dictionary;
public DictionarySerializationHelperClass()
{
}
public DictionarySerializationHelperClass(Dictionary<string, string> dict)
{
this.dictionary = dict;
}
}
I call the serialization like this:
DictionarySerializationHelperClass dictionaryClass = new DictionarySerializationHelperClass(XrmProperties.currentPluginContext);
return SerializationHelper.JsonSerialize(dictionaryClass);
And the serialization itself:
public static string JsonSerialize<T>(T objectToSerialize) where T : class, new()
{
string serialisedJson = null;
DataContractJsonSerializer serializer;
try
{
using (MemoryStream serializationStream = new MemoryStream())
{
if (typeof(T) == typeof(Dictionary<string, string>))
{
serializer = new DataContractJsonSerializer(typeof(T), new DataContractJsonSerializerSettings()
{
UseSimpleDictionaryFormat = true,
RootName = string.Empty
});
}
else
{
serializer = new DataContractJsonSerializer(typeof(T));
}
serializer.WriteObject(serializationStream, objectToSerialize);
serializationStream.Position = 0;
var reader = new StreamReader(serializationStream);
serialisedJson = reader.ReadToEnd();
}
}
catch (Exception ex)
{
string error = $"Error on Serializing JSON: \r\n\r\n{objectToSerialize}";
throw new JsonException(error, ex);
}
return serialisedJson;
}
The problem with the result is that I always get the following json which includes the root element "dictionary":
{
"dictionary":{
"source":"asdasdasd",
"correlationId":"asdasdasd",
"depth":"1",
"initiatingUserId":"asdasdasd",
"isInTransaction":"False",
"isolationMode":"2",
"message":"Retrieve",
"mode":"Synchronus",
"operationId":"asdasd",
"orgId":"esdfsdf",
"orgName":"asdasdasd",
"requestId":"asdasdasd",
"userId":"asdasdasd",
"entityId":"asdasdasd",
"entityName":"incident",
"type":"Plugin",
"stage":"Pre-operation"
}
}
How can I remove this root element to have finally the json looking like this?
{
"source":"asdasdasd",
"correlationId":"asdasdasd",
"depth":"1",
"initiatingUserId":"asdasdasd",
"isInTransaction":"False",
"isolationMode":"2",
"message":"Retrieve",
"mode":"Synchronus",
"operationId":"asdasd",
"orgId":"esdfsdf",
"orgName":"asdasdasd",
"requestId":"asdasdasd",
"userId":"asdasdasd",
"entityId":"asdasdasd",
"entityName":"incident",
"type":"Plugin",
"stage":"Pre-operation"
}
I've tried to set
Root = string.Empty
in the DataContractJsonSerializerSettings but it seems not to help.
Any hint is highly appreciated.

C# JSON Anonymous Type - Multiple properties with the same name

I am needing to produce this JSON string with C#:
{
"in0": {
"children": [
{
"ValueObjectDescriptor": {
"fields": [
{
"FieldDescriptor": {
"name": "length",
"xpath": "#lenth"
}
},
{
"FieldDescriptor": {
"name": "height",
"xpath": "#height"
}
},
{
"FieldDescriptor": {
"name": "width",
"xpath": "#width"
}
}
],
"objectName": "Job",
"limit": 1,
"xpathFilter": "#openJob = 'true'"
}
}
]
}
}
Here is my code:
static string BuildJsonString()
{
var json = new
{
in0 = new
{
children = new
{
ValueObjectDescriptor = new
{
fields = new
{
FieldDescriptor = new
{
name = "length",
xpath = "#length",
},
FieldDescriptor = new
{
name = "height",
xpath = "#height",
},
FieldDescriptor3 = new
{
name = "width",
xpath = "#width",
},
objectName = "Job",
limit = "1",
xpathFilter = "#openJob='true'"
}
}
}
}
};
var jsonFormatted = JsonConvert.SerializeObject(json, Newtonsoft.Json.Formatting.Indented);
return jsonFormatted.ToString();
The issue I am having is that the compiler doesn't like me using "FieldDescriptor" multiple times, I get the error "An anonymous type cannot have multiple properties with the same name".
I am very new to JSON, so any advice would be greatly appreciated.
Note that not only is having multiple fields with the same name invalid C# code, having duplicate keys in the same object is also invalid JSON. You can be sure that there is no JSON that would need you to write duplicate field names to serialise it.
The "FieldDescriptor" JSON keys are actually part of different JSON objects, and these JSON objects are all in a JSON array under the key "fields":
[
{
"FieldDescriptor": {
"name": "length",
"xpath": "#lenth"
}
},
{
"FieldDescriptor": {
"name": "height",
"xpath": "#height"
}
},
{
"FieldDescriptor": {
"name": "width",
"xpath": "#width"
}
}
]
The [ ... ] denotes the array, and each pair of { ... } denotes a JSON object. So you should create an (implicitly typed) array of anonymous objects, each one with the FieldDescriptor property, rather than one object having all three of the proeperties:
fields = new[] // <--- create an array
{
new {
FieldDescriptor = new
{
name = "length",
xpath = "#length",
}},
new { // notice the new pairs of curly braces
FieldDescriptor = new
{
name = "height",
xpath = "#height",
}}, // here's the closing brace
new {
FieldDescriptor3 = new
{
name = "width",
xpath = "#width",
}},
objectName = "Job",
limit = "1",
xpathFilter = "#openJob='true'"
}
It looks like in the json "fields" is an array of objects where each object contains a "FieldDescriptor" field. In your C# code you are creating "fields" as an object with multiple fields not an array of objects.

replacing keys in json with numbers which corresponds to enums

I'm making a json out of a class in c# and for making the json smaller i want to replace the string keys with numbers which correspond to a number of enums.
an example would be a json the looks like this:
{
"initdata":
{
"cell": {
"apn": "n",
"userName": "n",
"password": "n",
"number": "n"
},
"wifi": {
"mode": "AP",
"ssid": "m",
"password": ","
},
"ports": {
"p1": "k",
"p2": "y",
"p3": "5"
}
}
and enums that looks like this :
public enum celle { apn, userName, password, number };
public enum wifie { mode, ssid, password };
public enum portse { p1, p2, p3 };
public enum initdatae { cell , wifi , ports};
public enum settingse { initdata, timers }
and then I want the json to look like this :
{
"0":
{
"0": {
"0": "n",
"1": "n",
"2": "n",
"3": "n"
},
"1": {
"0": "AP",
"1": "m",
"2": ","
},
"2": {
"0": "k",
"1": "y",
"2": "5"
}
}
Thanks
If you are using Json.Net, for renaming the properties names, take a look here for exemple (there is plenty on Stack Overflow): Overwrite Json property name in c#
And for the values, I suggest you assign an int to each enum :
public enum celle
{
apn = 0,
userName = 1,
password = 2,
number = 3
};
And then you cast the enum to an int to get the value before converting it to json:
int celleValue = (int)celle.userName;
So, in the end your class will look like something like this:
public class ClassToConvert()
{
[JsonIgnore] // this property will not be on the json
public celle celleValue {get;set;}
[JsonProperty(PropertyName = "c1")]
public int celleShort
{
get
{
return (int)this.celleValue;
}
}
}
public enum celle
{
apn = 0,
userName = 1,
password = 2,
number = 3
};
If you don't have POCO's defined for your input JSON, you may rename your properties as follows:
deserialize the input JSON into an ExpandoObject
rename the ExpandoObject's properties as desired
serialize the ExpandoObject back to JSON:
public static void Main(string[] args)
{
var json = #"{
""initdata"": {
""cell"": {
""apn"": ""n"",
""userName"": ""n"",
""password"": ""n"",
""number"": ""n""
},
""wifi"": {
""mode"": ""AP"",
""ssid"": ""m"",
""password1"": "",""
},
""ports"": {
""p1"": ""k"",
""p2"": ""y"",
""p3"": ""5""
}
}
}";
dynamic obj = JsonConvert.DeserializeObject<ExpandoObject>(json, new ExpandoObjectConverter());
PrepareEnumIds();
RenameEnumProps(obj as ExpandoObject);
var shortJson = JsonConvert.SerializeObject(obj, Formatting.Indented);
Console.WriteLine(shortJson);
}
public static void RenameEnumProps(ExpandoObject expando)
{
var expandoDict = expando as IDictionary<string, object>;
var props = new List<string>(expandoDict.Keys);
for (var i = props.Count - 1; i >= 0; i--)
{
var child = expandoDict[props[i]];
if (child is ExpandoObject)
RenameEnumProps(child as ExpandoObject);
if (enumIds.ContainsKey(props[i]))
{
expandoDict.Add(enumIds[props[i]], child);
expandoDict.Remove(props[i]);
}
}
}
static Dictionary<string, string> enumIds = new Dictionary<string, string>();
static void PrepareEnumIds()
{
foreach (var enumType in new[] { typeof(celle), typeof(wifie), typeof(portse), typeof(initdatae), typeof(settingse) })
foreach (var enumValue in Enum.GetValues(enumType))
enumIds.Add(enumValue.ToString(), ((int)enumValue).ToString());
}
public enum celle { apn, userName, password, number };
public enum wifie { mode, ssid, password1 };
public enum portse { p1, p2, p3 };
public enum initdatae { cell, wifi, ports };
public enum settingse { initdata, timers }
Demo: https://dotnetfiddle.net/IPqxEQ
Note: I've cheated a little bit by changing one of the passwords values to make all enum values unique, sorry. This made renaming implementation significantly easier. But this does not affect the main point of implementation. I'll provide a complete implementation when I'll have some more spare time.

Help needed to convert a javascript object to corresponding C# dictionary

Hi I'm kind of newbie in C#, I have this javascript code that I need to convert into corresponding c# dictionary
given below is the javascript code
EXCHANGES = {
"ICE": {
source: "SPC",
name: "ICE Futures Europe",
assetTypes: {
CER: {
spot: "ECX CER DAILY FUTURE",
fut: "ECX CER FUTURE"
},
EUA: {
spot: "ECX EUA DAILY FUTURE",
fut: "ECX EUA FUTURE"
}
}
},
"CLIMEX": {
source: "CLX",
name: "Climex Spot Market",
symbols: {
CER: {
spot: ["CER"]
},
EUA: {
spot: ["EUA 08-12"]
}
}
},
"BLUENEXT": {
source: "BLNXT",
name: "Bluenext",
symbols: {
CER: {
spot: ["1000019-82-1"]
},
EUA: {
spot: ["1000019-81-1"]
}
}
}
};
So far what I have manage is this
public Dictionary<string, Dictionary<string, string>> Exchanges = new Dictionary<string, Dictionary<string, string>> {
{"ICE ECX", new Dictionary<string, string> {
{"source", "SPC"},
{"name", "ICE Futures Europe"},
{"exchange", "ICE" }
}},
{"Climex", new Dictionary<string, string> {
{"source", "CLX"},
{"name", "Climex Spot Market"},
{"exchange", "Climex" }
}},
{"BlueNext", new Dictionary<string, string> {
{"source", "BLNXT"},
{"name", "Bluenext"},
{"exchange", "BlueNext" }
}},
{"Green Exchange", new Dictionary<string, string> {
{"source", "SPC"},
{"name", "NYMEX: Futures"},
{"exchange", "NYMEX" }
}},
{"NYMEX_FA", new Dictionary<string, string> {
{"source", "SPC"},
{"name", "NYMEX: Futures Acess"},
{"exchange", "NYMEX_FA" }
}}
};
Can anyone of you can guide me to the correct way to do this any help will be appreciated.
thanks
Pranay
I'd use a JSON Parser. Like this.
In that way you can retrieve the properties and values after parsing from the JObject.
string jsonText = #"{
prop1: 1,
prop2: 'Some String',
'prop3': {
iProp1: 1,
iProp2: 2
}";
JObject parsedJson = JObject.Parse(jsonText);
I'd give a try to ExpandoObject, which is dynamic and implements IDictionary<string,object>. For instance, you can write the following code:
dynamic x = new ElasticObject();
x.Ice = new ExpandoObject();
x.Ice.Source = "SPC";
x.Ice.Name = "Ice Futures Europe";
x.AssetTypes = new ExpandoObject();
x.AssetTypes.CER = new ExpandoObject();
x.AssetTypes.CER.Spot = "EXC CER DAILY FUTURE";
x.AssetTypes.CER.Fut = "EXC CER FUTURE";
x.EUA = new ExpandoObject();
x.EUA.Spot = "ECX EUA DAILY FUTURE";
x.EUA.Fut = "ECX EUA FUTURE";
On MSDN you can read more about ExpandoObject here.
If you need a yet smarter object, there is the ElasticObject (described here). Using it you can skip the declaration of the nested Expandos, like this:
dynamic x = new ExpandoObject();
x.Ice.Source = "SPC";
x.Ice.Name = "Ice Futures Europe";
x.AssetTypes.CER.Spot = "EXC CER DAILY FUTURE";
x.AssetTypes.CER.Fut = "EXC CER FUTURE";
x.EUA.Spot = "ECX EUA DAILY FUTURE";
x.EUA.Fut = "ECX EUA FUTURE";
Hope this helps.
This what I did basically I created classes since maintaining this level of dictionary would have been cumbersome
public class Exchange
{
public string Source {get; set;}
public string Name {get; set;}
public Dictionary<string, AssetTypeSymbol> AssetTypes {get; set;}
public Dictionary <string,AssetTypeSymbol>Symbols {get; set;}
}
public class AssetTypeSymbol
{
public IList<string> Spot {get; set;}
public IList<string> Fut {get; set;}
}
public Dictionary<string,Exchange> Exchanges = new Dictionary<string,Exchange>
{
{"ICE ECX", new Exchange() {
Source = "SPC",
Name = "ICE Futures Europe",
AssetTypes = new Dictionary<string, AssetTypeSymbol>() {
{"CER", new AssetTypeSymbol() {
Spot = new string[] { "ECX CER DAILY FUTURE" },
Fut = new string[] { "ECX CER FUTURE" }
}},
.......... and so on

How to get google app engine logs in C#?

I am trying to retrieve app engine logs the only result I get is "# next_offset=None", below is my code:
internal string GetLogs()
{
string result = _connection.Get("/api/request_logs", GetPostParameters(null));
return result;
}
private Dictionary<string, string> GetPostParameters(Dictionary<string, string> customParameters)
{
Dictionary<string, string> parameters = new Dictionary<string, string>() {
{ "app_id", _settings.AppId },
{ "version", _settings.Version.ToString() }
};
if (customParameters != null)
{
foreach (string key in customParameters.Keys)
{
if (parameters.ContainsKey(key))
{
parameters[key] = customParameters[key];
}
else
{
parameters.Add(key, customParameters[key]);
}
}
}
return parameters;
}
This method requires version parameter to be version.1

Categories

Resources