Skip to content

Commit 7343dde

Browse files
Add support for the external object Dictionary. (#918)
* Add support for the external object Dictionary. * Simplify the RemoveKey method by removing the redundant ContainsKey condition.
1 parent a64b1a9 commit 7343dde

File tree

4 files changed

+236
-7
lines changed

4 files changed

+236
-7
lines changed

dotnet/src/dotnetframework/GxClasses/Domain/GxCollections.cs

Lines changed: 187 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ namespace GeneXus.Utils
1414
using System.Linq;
1515
using System.Reflection;
1616
using System.Runtime.Serialization;
17+
using System.Runtime.Serialization.Json;
1718
using System.Text;
1819
using System.Xml;
1920
using System.Xml.Serialization;
@@ -1563,13 +1564,25 @@ public void AddObjectProperty(string name, object prop, bool includeState)
15631564
public void AddObjectProperty(string name, object prop, bool includeState, bool includeNonInitialized)
15641565
{
15651566
IGxJSONAble ijsonProp = prop as IGxJSONAble;
1567+
IGxExternalObject extObj = prop as IGxExternalObject;
15661568
if (ijsonProp != null)
15671569
{
15681570
GxSilentTrnSdt silentTrn = prop as GxSilentTrnSdt;
15691571
if (silentTrn != null)
15701572
silentTrn.GetJSONObject(includeState, includeNonInitialized);
1571-
else
1573+
else if (extObj != null)
1574+
{
1575+
object extInstance = extObj.ExternalInstance;
1576+
IGxJSONAble gxJSONAble = extInstance as IGxJSONAble;
1577+
if (gxJSONAble != null)
1578+
{
1579+
JsonObj.Put(name, gxJSONAble.GetJSONObject(includeState));
1580+
}
1581+
}
1582+
else
1583+
{
15721584
JsonObj.Put(name, ijsonProp.GetJSONObject(includeState));
1585+
}
15731586
}
15741587
else
15751588
{
@@ -1703,7 +1716,14 @@ public void FromJSONObject(dynamic obj)
17031716
IGXBCCollection bcColl;
17041717
GxSimpleCollection<object> currSimpleColl;
17051718
IGxJSONAble currJsonProp;
1719+
IGxExternalObject currExtProp;
17061720
CollectionBase currObjColl = currObj as CollectionBase;
1721+
1722+
if ((currExtProp = currProp as IGxExternalObject) != null)
1723+
{
1724+
currProp = currExtProp.ExternalInstance;
1725+
}
1726+
17071727
#if !NETCORE
17081728
GxObjectCollectionBase currColl;
17091729
if ((currColl = currProp as GxObjectCollectionBase) != null)
@@ -2460,7 +2480,6 @@ public interface IGxCollection<T> : IGxCollection
24602480
{
24612481
T GetNumeric(int idx);
24622482
}
2463-
24642483
public interface IGxExternalObject
24652484
{
24662485
object ExternalInstance { get; set; }
@@ -2859,7 +2878,173 @@ public override string ToString()
28592878
}
28602879

28612880
}
2881+
public class GxGenericDictionary<TKey,TValue> : Dictionary<TKey,TValue>, IGxJSONSerializable, IGxJSONAble
2882+
{
2883+
private static readonly log4net.ILog log = log4net.LogManager.GetLogger(typeof(GxGenericDictionary<TKey, TValue>));
2884+
private readonly DataContractJsonSerializerSettings settings = new DataContractJsonSerializerSettings() { UseSimpleDictionaryFormat = true };
2885+
public void SetDictionary(GxGenericDictionary<TKey, TValue> dictionary)
2886+
{
2887+
foreach (var entry in dictionary)
2888+
{
2889+
this[entry.Key] = entry.Value;
2890+
}
2891+
}
2892+
2893+
public bool Get(TKey key, out TValue value)
2894+
{
2895+
if (TryGetValue(key, out value))
2896+
{
2897+
return true;
2898+
}
2899+
else
2900+
{
2901+
return false;
2902+
}
2903+
}
2904+
public TValue Get(TKey key)
2905+
{
2906+
if (TryGetValue(key, out TValue value))
2907+
{
2908+
return value;
2909+
2910+
}
2911+
else
2912+
{
2913+
return default;
2914+
}
2915+
}
2916+
public List<TValue> ValueList
2917+
{
2918+
get{
2919+
return base.Values.ToList();
2920+
}
2921+
}
2922+
public List<TKey> KeyList
2923+
{
2924+
get
2925+
{
2926+
return base.Keys.ToList();
2927+
}
2928+
}
2929+
public void Set(TKey key, TValue value)
2930+
{
2931+
base[key] = value;
2932+
}
2933+
2934+
public bool RemoveKey(TKey key)
2935+
{
2936+
return Remove(key);
2937+
}
2938+
2939+
public void RemoveKeys(List<TKey> keys)
2940+
{
2941+
foreach (var key in keys.ToList())
2942+
{
2943+
RemoveKey(key);
2944+
}
2945+
}
28622946

2947+
public void RemoveAll(GxGenericDictionary<TKey, TValue> dictionary)
2948+
{
2949+
foreach (var key in dictionary.Keys.ToList())
2950+
{
2951+
RemoveKey(key);
2952+
}
2953+
}
2954+
public string ToJson()
2955+
{
2956+
try
2957+
{
2958+
return JSONHelper.Serialize(this, settings);
2959+
}
2960+
catch (Exception e)
2961+
{
2962+
log.Error("Could not obtain JSON from Dictionary", e);
2963+
return "";
2964+
}
2965+
}
2966+
2967+
public void FromJson(string json)
2968+
{
2969+
try
2970+
{
2971+
Clear();
2972+
Dictionary<TKey, TValue> deserializedDictionary = JSONHelper.Deserialize<Dictionary<TKey, TValue>>(json, Encoding.Unicode, null, null, settings);
2973+
foreach (var entry in deserializedDictionary)
2974+
{
2975+
this[entry.Key] = entry.Value;
2976+
}
2977+
}
2978+
catch (Exception e)
2979+
{
2980+
log.Error("Could not set Dictionary from JSON", e);
2981+
}
2982+
}
2983+
2984+
public string ToJSonString()
2985+
{
2986+
return ToJson();
2987+
}
2988+
2989+
public bool FromJSonString(string s)
2990+
{
2991+
throw new NotImplementedException();
2992+
}
2993+
2994+
public bool FromJSonString(string s, GXBaseCollection<SdtMessages_Message> Messages)
2995+
{
2996+
throw new NotImplementedException();
2997+
}
2998+
2999+
public bool FromJSonFile(GxFile file)
3000+
{
3001+
throw new NotImplementedException();
3002+
}
3003+
3004+
public bool FromJSonFile(GxFile file, GXBaseCollection<SdtMessages_Message> Messages)
3005+
{
3006+
throw new NotImplementedException();
3007+
}
3008+
3009+
public void AddObjectProperty(string name, object prop)
3010+
{
3011+
throw new NotImplementedException();
3012+
}
3013+
3014+
public object GetJSONObject()
3015+
{
3016+
JObject jObj = new JObject();
3017+
foreach (TKey item in Keys)
3018+
{
3019+
jObj.Accumulate(item.ToString(), this[item]);
3020+
}
3021+
return jObj;
3022+
3023+
}
3024+
3025+
public object GetJSONObject(bool includeState)
3026+
{
3027+
return GetJSONObject();
3028+
}
3029+
3030+
public void FromJSONObject(dynamic obj)
3031+
{
3032+
this.Clear();
3033+
JObject jObj = obj as JObject;
3034+
if (jObj != null)
3035+
{
3036+
foreach (DictionaryEntry item in jObj)
3037+
{
3038+
base[(TKey)item.Key]= (TValue)item.Value;
3039+
}
3040+
}
3041+
}
3042+
3043+
public string ToJavascriptSource()
3044+
{
3045+
throw new NotImplementedException();
3046+
}
3047+
}
28633048
public class GxDictionary : Dictionary<string, Object>
28643049
{
28653050
public bool HasKey(string key)

dotnet/src/dotnetframework/GxClasses/Helpers/JSONHelper.cs

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ public static string Serialize<T>(T kbObject, Encoding encoding, IEnumerable<Typ
257257
{
258258
try
259259
{
260-
var settings = SerializationSettings(knownTypes);
260+
DataContractJsonSerializerSettings settings = SerializationSettings(knownTypes);
261261
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T), settings);
262262

263263
using (MemoryStream stream = new MemoryStream())
@@ -272,6 +272,24 @@ public static string Serialize<T>(T kbObject, Encoding encoding, IEnumerable<Typ
272272
}
273273
return null;
274274
}
275+
internal static string Serialize<T>(T kbObject, DataContractJsonSerializerSettings settings) where T : class
276+
{
277+
try
278+
{
279+
Encoding encoding = Encoding.UTF8;
280+
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T), settings);
281+
using (MemoryStream stream = new MemoryStream())
282+
{
283+
serializer.WriteObject(stream, kbObject);
284+
return encoding.GetString(stream.ToArray());
285+
}
286+
}
287+
catch (Exception ex)
288+
{
289+
GXLogging.Error(log, "Serialize error ", ex);
290+
}
291+
return null;
292+
}
275293
internal static string WCFSerialize<T>(T kbObject, Encoding encoding, IEnumerable<Type> knownTypes, bool useSimpleDictionaryFormat) where T : class
276294
{
277295
try
@@ -319,12 +337,16 @@ static DataContractJsonSerializerSettings WCFSerializationSettings(IEnumerable<T
319337
return Deserialize<T>(kbObject, encoding, knownTypes, new T());
320338
}
321339
public static T Deserialize<T>(string kbObject, Encoding encoding, IEnumerable<Type> knownTypes, T defaultValue) where T : class
340+
{
341+
var settings = SerializationSettings(knownTypes);
342+
return Deserialize<T>(kbObject, encoding, knownTypes, defaultValue, settings);
343+
}
344+
internal static T Deserialize<T>(string kbObject, Encoding encoding, IEnumerable<Type> knownTypes, T defaultValue, DataContractJsonSerializerSettings settings) where T : class
322345
{
323346
if (!string.IsNullOrEmpty(kbObject))
324347
{
325348
try
326349
{
327-
var settings = SerializationSettings(knownTypes);
328350
using (MemoryStream stream = new MemoryStream(encoding.GetBytes(kbObject)))
329351
{
330352
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T), settings);
@@ -342,14 +364,13 @@ public static T Deserialize<T>(string kbObject, Encoding encoding, IEnumerable<T
342364
}
343365
public static T Deserialize<T>(string kbObject, Encoding encoding) where T : class, new()
344366
{
345-
return Deserialize<T>(kbObject, Encoding.Unicode, null, new T());
367+
return Deserialize<T>(kbObject, encoding, null, new T());
346368
}
347369

348370
public static T Deserialize<T>(string kbObject) where T : class, new()
349371
{
350372
return Deserialize<T>(kbObject, Encoding.Unicode);
351373
}
352-
353374
public static T DeserializeNullDefaultValue<T>(string kbObject) where T : class
354375
{
355376
return Deserialize<T>(kbObject, Encoding.Unicode, null, null);

dotnet/test/DotNetCoreUnitTest/DotNetCoreUnitTest.csproj

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
</ItemGroup>
1616
<ItemGroup>
1717
<Compile Include="..\DotNetUnitTest\ConfigMappings\ConfigTest.cs" Link="ConfigMappings\ConfigTest.cs" />
18+
<Compile Include="..\DotNetUnitTest\Domain\GxGenericDictionaryTest.cs" Link="Domain\GxGenericDictionaryTest.cs" />
1819
<Compile Include="..\DotNetUnitTest\Domain\GxHttpClientTest.cs" Link="Domain\GxHttpClientTest.cs" />
1920
<Compile Include="..\DotNetUnitTest\Domain\ShellTest.cs" Link="Domain\ShellTest.cs" />
2021
<Compile Include="..\DotNetUnitTest\Domain\TimeZoneTest.cs" Link="Domain\TimeZoneTest.cs" />
@@ -73,7 +74,7 @@
7374
<PrivateAssets>all</PrivateAssets>
7475
</PackageReference>
7576
<PackageReference Include="Xunit.SkippableFact" Version="1.4.13" />
76-
<PackageReference Include="GemBox.Spreadsheet" Version="49.0.1454"/>
77+
<PackageReference Include="GemBox.Spreadsheet" Version="49.0.1454" />
7778
</ItemGroup>
7879

7980
<ItemGroup>
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
using GeneXus.Utils;
2+
using Xunit;
3+
4+
namespace xUnitTesting
5+
{
6+
public class GxGenericDictionaryTest
7+
{
8+
[Fact]
9+
public void ToJsonTest()
10+
{
11+
GxGenericDictionary<string, int> dic = new GxGenericDictionary<string, int>
12+
{
13+
{ "key1", 1 },
14+
{ "key2", 2 }
15+
};
16+
string json = dic.ToJson();
17+
string expectedJson = "{\"key1\":1,\"key2\":2}";
18+
Assert.Equal(expectedJson, json);
19+
}
20+
21+
}
22+
}

0 commit comments

Comments
 (0)