From cc6d8bebf902affe50119a3ba0c09918b527782c Mon Sep 17 00:00:00 2001 From: Claudia Murialdo Date: Tue, 26 Oct 2021 11:58:03 -0300 Subject: [PATCH 1/2] Add a converter to serialize properly the DBNull value according to the suggestion in https://github.com/dotnet/runtime/issues/418 Move duplicate code in GxRedis.cs and GxMemcached.cs to GxClasses.csproj Adding the package reference System.Text.Json to GxClasses.csproj gets a conflict with System.Net.Http. Because of that, HttpClient used in MapFunctions.cs is replaced by HttpWebRequest for .netframework similar to the use in GXGeolocation. --- .gitignore | 3 + .../GxClasses/Data/GXDataCommon.cs | 2 +- .../GxClasses/Domain/GXGeolocation.cs | 2 + .../GxClasses/GxClasses.csproj | 1 + .../GxClasses/Services/Caching/GxCache.cs | 55 +++++++++++++++++++ .../dotnetframework/GxMaps/MapFunctions.cs | 20 ++++++- .../Cache/GxMemcached/GxMemcached.cs | 43 +-------------- .../Providers/Cache/GxRedis/GxRedis.cs | 39 +------------ 8 files changed, 87 insertions(+), 78 deletions(-) diff --git a/.gitignore b/.gitignore index 76974049c..dfc726d36 100644 --- a/.gitignore +++ b/.gitignore @@ -358,3 +358,6 @@ build /dotnet/src/dotnetcore/GxNetCoreStartup/netcoreapp3.1/GxNetCoreStartup.deps.json /dotnet/src/dotnetcore/Reor/net5.0/Reor.deps.json /dotnet/src/dotnetcore/Reor/netcoreapp3.1/Reor.deps.json +/dotnet/src/dotnetcore/GxDataInitialization/net6.0/GXDataInitialization.deps.json +/dotnet/src/dotnetcore/GxNetCoreStartup/net6.0/GxNetCoreStartup.deps.json +/dotnet/src/dotnetcore/Reor/net6.0/Reor.deps.json diff --git a/dotnet/src/dotnetframework/GxClasses/Data/GXDataCommon.cs b/dotnet/src/dotnetframework/GxClasses/Data/GXDataCommon.cs index 676bcf8ca..fc61cc0b4 100644 --- a/dotnet/src/dotnetframework/GxClasses/Data/GXDataCommon.cs +++ b/dotnet/src/dotnetframework/GxClasses/Data/GXDataCommon.cs @@ -4298,7 +4298,7 @@ public object GetValue(int i) } public virtual bool IsDBNull(int i) { - return (block.Item(pos, i) == DBNull.Value) || (block.Item(pos, i) is DBNull); + return (block.Item(pos, i) == DBNull.Value) || (block.Item(pos, i) is DBNull || block.Item(pos, i) == null); } public char GetChar(int i) { diff --git a/dotnet/src/dotnetframework/GxClasses/Domain/GXGeolocation.cs b/dotnet/src/dotnetframework/GxClasses/Domain/GXGeolocation.cs index cf9d9c0cb..6dff7a7de 100644 --- a/dotnet/src/dotnetframework/GxClasses/Domain/GXGeolocation.cs +++ b/dotnet/src/dotnetframework/GxClasses/Domain/GXGeolocation.cs @@ -10,7 +10,9 @@ using System.Globalization; using GeneXus; using GeneXus.Configuration; +#if NETCORE using System.Net.Http; +#endif namespace GX { diff --git a/dotnet/src/dotnetframework/GxClasses/GxClasses.csproj b/dotnet/src/dotnetframework/GxClasses/GxClasses.csproj index 9937350ca..781feb10d 100644 --- a/dotnet/src/dotnetframework/GxClasses/GxClasses.csproj +++ b/dotnet/src/dotnetframework/GxClasses/GxClasses.csproj @@ -18,6 +18,7 @@ + False ..\libs\Microsoft.HostIntegration.MsDb2Client.dll diff --git a/dotnet/src/dotnetframework/GxClasses/Services/Caching/GxCache.cs b/dotnet/src/dotnetframework/GxClasses/Services/Caching/GxCache.cs index b4293e3c4..f5c80ff12 100644 --- a/dotnet/src/dotnetframework/GxClasses/Services/Caching/GxCache.cs +++ b/dotnet/src/dotnetframework/GxClasses/Services/Caching/GxCache.cs @@ -12,6 +12,9 @@ using System.Collections.Generic; using GeneXus.Services; using System.Linq; +using System.Security; +using System.Text.Json.Serialization; +using System.Text.Json; #if NETCORE using GxClasses.Helpers; using System.IO; @@ -37,6 +40,58 @@ public interface ICacheService2 : ICacheService IDictionary GetAll(string cacheid, IEnumerable keys); void SetAll(string cacheid, IEnumerable keys, IEnumerable values, int durationMinutes = 0); } + [SecurityCritical] + public class DBNullConverter : JsonConverter + { + [SecurityCritical] + public override DBNull Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + throw new NotSupportedException(); + } + [SecurityCritical] + public override void Write(Utf8JsonWriter writer, DBNull value, JsonSerializerOptions options) + { + writer.WriteNullValue(); + } + } + [SecurityCritical] + public class ObjectToInferredTypesConverter : JsonConverter + { + [SecurityCritical] + public override bool CanConvert(Type typeToConvert) + { + return typeof(object) == typeToConvert; + } + [SecurityCritical] + public override object Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + switch (reader.TokenType) + { + case JsonTokenType.True: + return true; + case JsonTokenType.False: + return false; + case JsonTokenType.Number: + if (reader.TryGetInt64(out long l)) + return l; + else return reader.GetDouble(); + case JsonTokenType.String: + if (reader.TryGetDateTime(out DateTime datetime)) + return datetime; + else return reader.GetString(); + default: + using (JsonDocument document = JsonDocument.ParseValue(ref reader)) + { + return document.RootElement.Clone().ToString(); + } + } + } + [SecurityCritical] + public override void Write(Utf8JsonWriter writer, object value, JsonSerializerOptions options) + { + throw new NotImplementedException(); + } + } public class CacheFactory { diff --git a/dotnet/src/dotnetframework/GxMaps/MapFunctions.cs b/dotnet/src/dotnetframework/GxMaps/MapFunctions.cs index 105651c81..d57d6bb31 100644 --- a/dotnet/src/dotnetframework/GxMaps/MapFunctions.cs +++ b/dotnet/src/dotnetframework/GxMaps/MapFunctions.cs @@ -7,7 +7,11 @@ using GeneXus.Utils; using System.IO; using System.Globalization; +using System.Net; +using System.Text; +#if NETCORE using System.Net.Http; +#endif namespace GeneXus.MapServices { @@ -121,9 +125,22 @@ public static LocationInfo GetCurrentLocation(int minAccuracy, int timeout, bool if (Application.GxContext.IsHttpContext) { string ip = Application.GxContext.Current.GetRemoteAddress(); + string urlString = "http://ipinfo.io/" + ip; +#if !NETCORE + HttpWebRequest req = (HttpWebRequest)WebRequest.Create(new Uri(urlString)); + req.Method = "GET"; + HttpWebResponse resp = (HttpWebResponse)req.GetResponse(); + + Stream rStream = resp.GetResponseStream(); + using (StreamReader readStream = new StreamReader(rStream, Encoding.UTF8)) + { + string info = readStream.ReadToEnd(); + } + rStream.Close(); +#else using (HttpClient client = new HttpClient()) { - using (HttpResponseMessage response = client.GetAsync(new Uri("http://ipinfo.io/" + ip)).Result) + using (HttpResponseMessage response = client.GetAsync(new Uri(urlString)).Result) { using (HttpContent content = response.Content) { @@ -131,6 +148,7 @@ public static LocationInfo GetCurrentLocation(int minAccuracy, int timeout, bool } } } +#endif return new LocationInfo { }; } return new LocationInfo { }; diff --git a/dotnet/src/dotnetframework/Providers/Cache/GxMemcached/GxMemcached.cs b/dotnet/src/dotnetframework/Providers/Cache/GxMemcached/GxMemcached.cs index fa5a8f153..d1636a1c4 100644 --- a/dotnet/src/dotnetframework/Providers/Cache/GxMemcached/GxMemcached.cs +++ b/dotnet/src/dotnetframework/Providers/Cache/GxMemcached/GxMemcached.cs @@ -215,7 +215,9 @@ static string Serialize(object o) { return null; } - return JsonSerializer.Serialize(o); + JsonSerializerOptions opts = new JsonSerializerOptions(); + opts.Converters.Add(new DBNullConverter()); + return JsonSerializer.Serialize(o, opts); } [SecurityCritical] static T Deserialize(string value) @@ -229,43 +231,4 @@ static T Deserialize(string value) return JsonSerializer.Deserialize(value, opts); } } - [SecurityCritical] - public class ObjectToInferredTypesConverter : JsonConverter - { - [SecurityCritical] - public override bool CanConvert(Type typeToConvert) - { - return typeof(object) == typeToConvert; - } - [SecurityCritical] - public override object Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - switch (reader.TokenType) - { - case JsonTokenType.True: - return true; - case JsonTokenType.False: - return false; - case JsonTokenType.Number: - if (reader.TryGetInt64(out long l)) - return l; - else return reader.GetDouble(); - case JsonTokenType.String: - if (reader.TryGetDateTime(out DateTime datetime)) - return datetime; - else return reader.GetString(); - default: - using (JsonDocument document = JsonDocument.ParseValue(ref reader)) - { - return document.RootElement.Clone().ToString(); - } - } - } - [SecurityCritical] - public override void Write(Utf8JsonWriter writer, object value, JsonSerializerOptions options) - { - throw new NotImplementedException(); - } - } - } diff --git a/dotnet/src/dotnetframework/Providers/Cache/GxRedis/GxRedis.cs b/dotnet/src/dotnetframework/Providers/Cache/GxRedis/GxRedis.cs index 5df22c7db..91a60e8c2 100644 --- a/dotnet/src/dotnetframework/Providers/Cache/GxRedis/GxRedis.cs +++ b/dotnet/src/dotnetframework/Providers/Cache/GxRedis/GxRedis.cs @@ -205,7 +205,9 @@ static string Serialize(object o) { return null; } - return JsonSerializer.Serialize(o); + JsonSerializerOptions opts = new JsonSerializerOptions(); + opts.Converters.Add(new DBNullConverter()); + return JsonSerializer.Serialize(o, opts); } static T Deserialize(string value) @@ -219,39 +221,4 @@ static T Deserialize(string value) return JsonSerializer.Deserialize(value, opts); } } - public class ObjectToInferredTypesConverter: JsonConverter - { - public override bool CanConvert(Type typeToConvert) - { - return typeof(object) == typeToConvert; - } - public override object Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - switch (reader.TokenType) - { - case JsonTokenType.True: - return true; - case JsonTokenType.False: - return false; - case JsonTokenType.Number: - if (reader.TryGetInt64(out long l)) - return l; - else return reader.GetDouble(); - case JsonTokenType.String: - if (reader.TryGetDateTime(out DateTime datetime)) - return datetime; - else return reader.GetString(); - default: - using (JsonDocument document = JsonDocument.ParseValue(ref reader)) - { - return document.RootElement.Clone().ToString(); - } - } - } - - public override void Write(Utf8JsonWriter writer, object value, JsonSerializerOptions options) - { - throw new NotImplementedException(); - } - } } \ No newline at end of file From 7b67ae93bf0619c6ecb2d13adb5ad435e6dec03b Mon Sep 17 00:00:00 2001 From: Claudia Murialdo Date: Tue, 26 Oct 2021 17:41:54 -0300 Subject: [PATCH 2/2] Remove unused code. --- .../dotnetframework/GxMaps/MapFunctions.cs | 34 ------------------- 1 file changed, 34 deletions(-) diff --git a/dotnet/src/dotnetframework/GxMaps/MapFunctions.cs b/dotnet/src/dotnetframework/GxMaps/MapFunctions.cs index d57d6bb31..e04d0de9b 100644 --- a/dotnet/src/dotnetframework/GxMaps/MapFunctions.cs +++ b/dotnet/src/dotnetframework/GxMaps/MapFunctions.cs @@ -7,11 +7,6 @@ using GeneXus.Utils; using System.IO; using System.Globalization; -using System.Net; -using System.Text; -#if NETCORE -using System.Net.Http; -#endif namespace GeneXus.MapServices { @@ -122,35 +117,6 @@ private static Assembly LoadAssembly(string fileName) public static LocationInfo GetCurrentLocation(int minAccuracy, int timeout, bool includeHAndS, bool ignoreErrors) { - if (Application.GxContext.IsHttpContext) - { - string ip = Application.GxContext.Current.GetRemoteAddress(); - string urlString = "http://ipinfo.io/" + ip; -#if !NETCORE - HttpWebRequest req = (HttpWebRequest)WebRequest.Create(new Uri(urlString)); - req.Method = "GET"; - HttpWebResponse resp = (HttpWebResponse)req.GetResponse(); - - Stream rStream = resp.GetResponseStream(); - using (StreamReader readStream = new StreamReader(rStream, Encoding.UTF8)) - { - string info = readStream.ReadToEnd(); - } - rStream.Close(); -#else - using (HttpClient client = new HttpClient()) - { - using (HttpResponseMessage response = client.GetAsync(new Uri(urlString)).Result) - { - using (HttpContent content = response.Content) - { - string info = content.ReadAsStringAsync().Result; - } - } - } -#endif - return new LocationInfo { }; - } return new LocationInfo { }; }