Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for the external object Dictionary. #918

Merged
merged 2 commits into from
Apr 17, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
193 changes: 191 additions & 2 deletions dotnet/src/dotnetframework/GxClasses/Domain/GxCollections.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ namespace GeneXus.Utils
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
Expand Down Expand Up @@ -1560,13 +1561,25 @@ public void AddObjectProperty(string name, object prop, bool includeState)
public void AddObjectProperty(string name, object prop, bool includeState, bool includeNonInitialized)
{
IGxJSONAble ijsonProp = prop as IGxJSONAble;
IGxExternalObject extObj = prop as IGxExternalObject;
if (ijsonProp != null)
{
GxSilentTrnSdt silentTrn = prop as GxSilentTrnSdt;
if (silentTrn != null)
silentTrn.GetJSONObject(includeState, includeNonInitialized);
else
else if (extObj != null)
{
object extInstance = extObj.ExternalInstance;
IGxJSONAble gxJSONAble = extInstance as IGxJSONAble;
if (gxJSONAble != null)
{
JsonObj.Put(name, gxJSONAble.GetJSONObject(includeState));
}
}
else
{
JsonObj.Put(name, ijsonProp.GetJSONObject(includeState));
}
}
else
{
Expand Down Expand Up @@ -1699,7 +1712,14 @@ public void FromJSONObject(dynamic obj)
IGXBCCollection bcColl;
GxSimpleCollection<object> currSimpleColl;
IGxJSONAble currJsonProp;
IGxExternalObject currExtProp;
CollectionBase currObjColl = currObj as CollectionBase;

if ((currExtProp = currProp as IGxExternalObject) != null)
{
currProp = currExtProp.ExternalInstance;
}

#if !NETCORE
GxObjectCollectionBase currColl;
if ((currColl = currProp as GxObjectCollectionBase) != null)
Expand Down Expand Up @@ -2434,7 +2454,6 @@ public interface IGxCollection<T> : IGxCollection
{
T GetNumeric(int idx);
}

public interface IGxExternalObject
{
object ExternalInstance { get; set; }
Expand Down Expand Up @@ -2833,7 +2852,177 @@ public override string ToString()
}

}
public class GxGenericDictionary<TKey,TValue> : Dictionary<TKey,TValue>, IGxJSONSerializable, IGxJSONAble
{
private static readonly log4net.ILog log = log4net.LogManager.GetLogger(typeof(GxGenericDictionary<TKey, TValue>));
private readonly DataContractJsonSerializerSettings settings = new DataContractJsonSerializerSettings() { UseSimpleDictionaryFormat = true };
public void SetDictionary(GxGenericDictionary<TKey, TValue> dictionary)
{
foreach (var entry in dictionary)
{
this[entry.Key] = entry.Value;
}
}

public bool Get(TKey key, out TValue value)
{
if (TryGetValue(key, out value))
{
return true;
}
else
{
return false;
}
}
public TValue Get(TKey key)
{
if (TryGetValue(key, out TValue value))
{
return value;

}
else
{
return default;
}
}
public List<TValue> ValueList
{
get{
return base.Values.ToList();
}
}
public List<TKey> KeyList
{
get
{
return base.Keys.ToList();
}
}
public void Set(TKey key, TValue value)
{
base[key] = value;
}

public bool RemoveKey(TKey key)
{
if (ContainsKey(key))
{
return Remove(key);
claudiamurialdo marked this conversation as resolved.
Show resolved Hide resolved
}
return false;
}

public void RemoveKeys(List<TKey> keys)
{
foreach (var key in keys.ToList())
{
RemoveKey(key);
}
}

public void RemoveAll(GxGenericDictionary<TKey, TValue> dictionary)
{
foreach (var key in dictionary.Keys.ToList())
{
RemoveKey(key);
}
}
public string ToJson()
{
try
{
return JSONHelper.Serialize(this, settings);
}
catch (Exception e)
{
log.Error("Could not obtain JSON from Dictionary", e);
return "";
}
}

public void FromJson(string json)
{
try
{
Clear();
Dictionary<TKey, TValue> deserializedDictionary = JSONHelper.Deserialize<Dictionary<TKey, TValue>>(json, Encoding.Unicode, null, null, settings);
foreach (var entry in deserializedDictionary)
{
this[entry.Key] = entry.Value;
}
}
catch (Exception e)
{
log.Error("Could not set Dictionary from JSON", e);
}
}

public string ToJSonString()
{
return ToJson();
}

public bool FromJSonString(string s)
{
throw new NotImplementedException();
}

public bool FromJSonString(string s, GXBaseCollection<SdtMessages_Message> Messages)
{
throw new NotImplementedException();
}

public bool FromJSonFile(GxFile file)
{
throw new NotImplementedException();
}

public bool FromJSonFile(GxFile file, GXBaseCollection<SdtMessages_Message> Messages)
{
throw new NotImplementedException();
}

public void AddObjectProperty(string name, object prop)
{
throw new NotImplementedException();
}

public object GetJSONObject()
{
JObject jObj = new JObject();
foreach (TKey item in Keys)
{
jObj.Accumulate(item.ToString(), this[item]);
}
return jObj;

}

public object GetJSONObject(bool includeState)
{
return GetJSONObject();
}

public void FromJSONObject(dynamic obj)
{
this.Clear();
JObject jObj = obj as JObject;
if (jObj != null)
{
foreach (DictionaryEntry item in jObj)
{
base[(TKey)item.Key]= (TValue)item.Value;
}
}
}

public string ToJavascriptSource()
{
throw new NotImplementedException();
}
}
public class GxDictionary : Dictionary<string, Object>
{
public bool HasKey(string key)
Expand Down
29 changes: 25 additions & 4 deletions dotnet/src/dotnetframework/GxClasses/Helpers/JSONHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ public static string Serialize<T>(T kbObject, Encoding encoding, IEnumerable<Typ
{
try
{
var settings = SerializationSettings(knownTypes);
DataContractJsonSerializerSettings settings = SerializationSettings(knownTypes);
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T), settings);

using (MemoryStream stream = new MemoryStream())
Expand All @@ -229,6 +229,24 @@ public static string Serialize<T>(T kbObject, Encoding encoding, IEnumerable<Typ
}
return null;
}
internal static string Serialize<T>(T kbObject, DataContractJsonSerializerSettings settings) where T : class
{
try
{
Encoding encoding = Encoding.UTF8;
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T), settings);
using (MemoryStream stream = new MemoryStream())
{
serializer.WriteObject(stream, kbObject);
return encoding.GetString(stream.ToArray());
}
}
catch (Exception ex)
{
GXLogging.Error(log, "Serialize error ", ex);
}
return null;
}
internal static string WCFSerialize<T>(T kbObject, Encoding encoding, IEnumerable<Type> knownTypes, bool useSimpleDictionaryFormat) where T : class
{
try
Expand Down Expand Up @@ -276,12 +294,16 @@ static DataContractJsonSerializerSettings WCFSerializationSettings(IEnumerable<T
return Deserialize<T>(kbObject, encoding, knownTypes, new T());
}
public static T Deserialize<T>(string kbObject, Encoding encoding, IEnumerable<Type> knownTypes, T defaultValue) where T : class
{
var settings = SerializationSettings(knownTypes);
return Deserialize<T>(kbObject, encoding, knownTypes, defaultValue, settings);
}
internal static T Deserialize<T>(string kbObject, Encoding encoding, IEnumerable<Type> knownTypes, T defaultValue, DataContractJsonSerializerSettings settings) where T : class
{
if (!string.IsNullOrEmpty(kbObject))
{
try
{
var settings = SerializationSettings(knownTypes);
using (MemoryStream stream = new MemoryStream(encoding.GetBytes(kbObject)))
{
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T), settings);
Expand All @@ -299,14 +321,13 @@ public static T Deserialize<T>(string kbObject, Encoding encoding, IEnumerable<T
}
public static T Deserialize<T>(string kbObject, Encoding encoding) where T : class, new()
{
return Deserialize<T>(kbObject, Encoding.Unicode, null, new T());
return Deserialize<T>(kbObject, encoding, null, new T());
}

public static T Deserialize<T>(string kbObject) where T : class, new()
{
return Deserialize<T>(kbObject, Encoding.Unicode);
}

public static T DeserializeNullDefaultValue<T>(string kbObject) where T : class
{
return Deserialize<T>(kbObject, Encoding.Unicode, null, null);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -804,8 +804,10 @@ protected Task Serialize(object value)
#else
var responseStream = _httpContext.Response.OutputStream;
#endif
var knownTypes = new List<Type>();
knownTypes.Add(value.GetType());
var knownTypes = new List<Type>
{
value.GetType()
};

JSONHelper.WCFSerialize(value, Encoding.UTF8, knownTypes, responseStream);
return Task.CompletedTask;
Expand Down
3 changes: 2 additions & 1 deletion dotnet/test/DotNetCoreUnitTest/DotNetCoreUnitTest.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="..\DotNetUnitTest\ConfigMappings\ConfigTest.cs" Link="ConfigMappings\ConfigTest.cs" />
<Compile Include="..\DotNetUnitTest\Domain\GxGenericDictionaryTest.cs" Link="Domain\GxGenericDictionaryTest.cs" />
<Compile Include="..\DotNetUnitTest\Domain\GxHttpClientTest.cs" Link="Domain\GxHttpClientTest.cs" />
<Compile Include="..\DotNetUnitTest\Domain\ShellTest.cs" Link="Domain\ShellTest.cs" />
<Compile Include="..\DotNetUnitTest\Domain\TimeZoneTest.cs" Link="Domain\TimeZoneTest.cs" />
Expand Down Expand Up @@ -74,7 +75,7 @@
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Xunit.SkippableFact" Version="1.4.13" />
<PackageReference Include="GemBox.Spreadsheet" Version="49.0.1454"/>
<PackageReference Include="GemBox.Spreadsheet" Version="49.0.1454" />
</ItemGroup>

<ItemGroup>
Expand Down
22 changes: 22 additions & 0 deletions dotnet/test/DotNetUnitTest/Domain/GxGenericDictionaryTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using GeneXus.Utils;
using Xunit;

namespace xUnitTesting
{
public class GxGenericDictionaryTest
{
[Fact]
public void ToJsonTest()
{
GxGenericDictionary<string, int> dic = new GxGenericDictionary<string, int>
{
{ "key1", 1 },
{ "key2", 2 }
};
string json = dic.ToJson();
string expectedJson = "{\"key1\":1,\"key2\":2}";
Assert.Equal(expectedJson, json);
}

}
}
Loading