diff --git a/net/DevExtreme.AspNet.Data.Tests/DeserializeTests.cs b/net/DevExtreme.AspNet.Data.Tests/DeserializeTests.cs index 5f57da8d..aecc816c 100644 --- a/net/DevExtreme.AspNet.Data.Tests/DeserializeTests.cs +++ b/net/DevExtreme.AspNet.Data.Tests/DeserializeTests.cs @@ -1,25 +1,23 @@ -using System.Collections; +using DevExtreme.AspNet.Data.Helpers; + +using System.Collections; using System.Text.Json; using Xunit; namespace DevExtreme.AspNet.Data.Tests { public class DeserializeTests { - static readonly JsonSerializerOptions TESTS_DEFAULT_SERIALIZER_OPTIONS = new JsonSerializerOptions(JsonSerializerDefaults.Web) { - Converters = { new ListConverter() } - }; - [Theory] [InlineData(@"[""fieldName"",""="",null]")] [InlineData(@"[[""fieldName1"",""="",""""],""and"",[""fieldName2"",""="",null]]")] public void FilterOperandValueCanBeNull(string rawJsonCriteria) { - var deserializedList = JsonSerializer.Deserialize(rawJsonCriteria, TESTS_DEFAULT_SERIALIZER_OPTIONS); + var deserializedList = JsonSerializer.Deserialize(rawJsonCriteria, DataSourceLoadOptionsParser.DEFAULT_SERIALIZER_OPTIONS); Assert.Equal(3, deserializedList.Count); } [Fact] public void FilterOperandValueCanBeObject() { - var deserializedList = JsonSerializer.Deserialize(@"[""fieldName1"",""="",{""Value"":0}]", TESTS_DEFAULT_SERIALIZER_OPTIONS); + var deserializedList = JsonSerializer.Deserialize(@"[""fieldName1"",""="",{""Value"":0}]", DataSourceLoadOptionsParser.DEFAULT_SERIALIZER_OPTIONS); Assert.Equal(3, deserializedList.Count); Assert.Equal("{\"Value\":0}", deserializedList[2].ToString()); } diff --git a/net/DevExtreme.AspNet.Data.Tests/SerializeTests.cs b/net/DevExtreme.AspNet.Data.Tests/SerializeTests.cs new file mode 100644 index 00000000..32dee49e --- /dev/null +++ b/net/DevExtreme.AspNet.Data.Tests/SerializeTests.cs @@ -0,0 +1,61 @@ +//using DevExtreme.AspNet.Data.Helpers; + +using System; +using System.Collections.Generic; +using System.Text.Json; +using Xunit; + +namespace DevExtreme.AspNet.Data.Tests { + + public class SerializeTests { + [Fact] + public void SerializeEmptyOptions() { + Assert.Equal(@"{""RequireTotalCount"":false,""RequireGroupCount"":false,""IsCountQuery"":false,""IsSummaryQuery"":false,""Skip"":0,""Take"":0,""Sort"":null,""Group"":null,""Filter"":null,""TotalSummary"":null,""GroupSummary"":null,""Select"":null,""PreSelect"":null,""RemoteSelect"":null,""RemoteGrouping"":null,""ExpandLinqSumType"":null,""PrimaryKey"":null,""DefaultSort"":null,""StringToLower"":null,""PaginateViaPrimaryKey"":null,""SortByPrimaryKey"":null,""AllowAsyncOverSync"":false}", + JsonSerializer.Serialize(new DataSourceLoadOptionsBase())); + } + + [Fact] + public void SerializeDeserializeConvertersAffectedOptions() { + var loadOptionsStrGroup = @"""Group"":[{""GroupInterval"":""100"",""IsExpanded"":null,""Selector"":""freight"",""Desc"":false}]"; + var loadOptionsStrFilter = @"""Filter"":[[""orderDate"",""\u003E="",""2011-12-13T14:15:16""],""and"",[""orderDate"",""\u003C"",""2011-12-13T14:15:17""]]"; + + var loadOptions = new DataSourceLoadOptionsBase() { + Group = new GroupingInfo[] { + new GroupingInfo() { + GroupInterval = "100", + Selector = "freight" + } + }, + Filter = new List() { + new List() { "orderDate", ">=", new DateTime(2011, 12, 13, 14, 15, 16) }, + "and", + new List() { "orderDate", "<", new DateTime(2011, 12, 13, 14, 15, 17) } + } + }; + + var loadOptionsSerialized = JsonSerializer.Serialize(loadOptions); + Assert.Contains($"{loadOptionsStrGroup},{loadOptionsStrFilter}", loadOptionsSerialized); + + var loadOptionsDeserialized = JsonSerializer.Deserialize( + loadOptionsSerialized + //, DataSourceLoadOptionsParser.DEFAULT_SERIALIZER_OPTIONS + // does not require options, because deserializes from just serialized instance + ); + Assert.Equal(loadOptions.Group[0].GroupInterval, loadOptionsDeserialized.Group[0].GroupInterval); + Assert.Equal(loadOptions.Group[0].Selector, loadOptionsDeserialized.Group[0].Selector); + Assert.Equal(loadOptions.Filter.Count, loadOptionsDeserialized.Filter.Count); + var filter0Orig = (IList)loadOptions.Filter[0]; + var filter0STJ = (IList)loadOptionsDeserialized.Filter[0]; + Assert.Equal(filter0Orig[0], filter0STJ[0]); + Assert.Equal(filter0Orig[1], filter0STJ[1]); + //TODO: + //https://github.com/dotnet/runtime/issues/31423 + //https://learn.microsoft.com/en-us/dotnet/standard/datetime/system-text-json-support + //https://github.com/DevExpress/DevExtreme.AspNet.Data/blob/master/js/dx.aspnet.data.js -> serializeDate + //Assert.Equal(filter0Orig[2], filter0STJ[2]); + Assert.Equal("2011-12-13T14:15:16", filter0STJ[2]); + + } + } + +} diff --git a/net/DevExtreme.AspNet.Data.Tests/SerializeTestsEx.cs b/net/DevExtreme.AspNet.Data.Tests/SerializeTestsEx.cs new file mode 100644 index 00000000..324e1f02 --- /dev/null +++ b/net/DevExtreme.AspNet.Data.Tests/SerializeTestsEx.cs @@ -0,0 +1,52 @@ +#if NEWTONSOFT_TESTS +using System; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using Xunit; + +namespace DevExtreme.AspNet.Data.Tests { + + public class SerializeTestsEx { + [Fact] + public void SerializeEmptyOptions() { + Assert.Equal(@"{""RequireTotalCount"":false,""RequireGroupCount"":false,""IsCountQuery"":false,""IsSummaryQuery"":false,""Skip"":0,""Take"":0,""Sort"":null,""Group"":null,""Filter"":null,""TotalSummary"":null,""GroupSummary"":null,""Select"":null,""PreSelect"":null,""RemoteSelect"":null,""RemoteGrouping"":null,""ExpandLinqSumType"":null,""PrimaryKey"":null,""DefaultSort"":null,""StringToLower"":null,""PaginateViaPrimaryKey"":null,""SortByPrimaryKey"":null,""AllowAsyncOverSync"":false}", + JsonConvert.SerializeObject(new DataSourceLoadOptionsBase())); + } + + [Fact] + public void SerializeDeserializeConvertersAffectedOptions() { + var loadOptionsStrGroup = @"""Group"":[{""GroupInterval"":""100"",""IsExpanded"":null,""Selector"":""freight"",""Desc"":false}]"; + var loadOptionsStrFilter = @"""Filter"":[[""orderDate"","">="",""2011-12-13T14:15:16""],""and"",[""orderDate"",""<"",""2011-12-13T14:15:17""]]"; + + var loadOptions = new DataSourceLoadOptionsBase() { + Group = new GroupingInfo[] { + new GroupingInfo() { + GroupInterval = "100", + Selector = "freight" + } + }, + Filter = new List() { + new List() { "orderDate", ">=", new DateTime(2011, 12, 13, 14, 15, 16) }, + "and", + new List() { "orderDate", "<", new DateTime(2011, 12, 13, 14, 15, 17) } + } + }; + + var loadOptionsSerialized = JsonConvert.SerializeObject(loadOptions); + Assert.Contains($"{loadOptionsStrGroup},{loadOptionsStrFilter}", loadOptionsSerialized); + + var loadOptionsDeserialized = JsonConvert.DeserializeObject(loadOptionsSerialized); + Assert.Equal(loadOptions.Group[0].GroupInterval, loadOptionsDeserialized.Group[0].GroupInterval); + Assert.Equal(loadOptions.Group[0].Selector, loadOptionsDeserialized.Group[0].Selector); + Assert.Equal(loadOptions.Filter.Count, loadOptionsDeserialized.Filter.Count); + var filter0Orig = (IList)loadOptions.Filter[0]; + var filter0NTSF = (JArray)loadOptionsDeserialized.Filter[0]; + Assert.Equal(filter0Orig[0], ((JValue)filter0NTSF[0]).Value); + Assert.Equal(filter0Orig[1], ((JValue)filter0NTSF[1]).Value); + Assert.Equal(filter0Orig[2], ((JValue)filter0NTSF[2]).Value); + } + } + +} +#endif diff --git a/net/DevExtreme.AspNet.Data/Compatibility.cs b/net/DevExtreme.AspNet.Data/Compatibility.cs index ecdc0c6f..af4cc6e8 100644 --- a/net/DevExtreme.AspNet.Data/Compatibility.cs +++ b/net/DevExtreme.AspNet.Data/Compatibility.cs @@ -66,7 +66,7 @@ static object GetNumber(ref Utf8JsonReader reader) { throw new NotImplementedException(); } - public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options) => throw new NotImplementedException(); + public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options) => writer.WriteStringValue(value); } class ListConverter : JsonConverter { @@ -75,7 +75,7 @@ public override IList Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSe return Compatibility.UnwrapList(deserializedList); } - public override void Write(Utf8JsonWriter writer, IList value, JsonSerializerOptions options) => throw new NotImplementedException(); + public override void Write(Utf8JsonWriter writer, IList value, JsonSerializerOptions options) => JsonSerializer.Serialize(writer, value, value.GetType(), options); } } diff --git a/net/DevExtreme.AspNet.Data/Helpers/DataSourceLoadOptionsParser.cs b/net/DevExtreme.AspNet.Data/Helpers/DataSourceLoadOptionsParser.cs index 85403e0f..b9ee9303 100644 --- a/net/DevExtreme.AspNet.Data/Helpers/DataSourceLoadOptionsParser.cs +++ b/net/DevExtreme.AspNet.Data/Helpers/DataSourceLoadOptionsParser.cs @@ -8,6 +8,9 @@ namespace DevExtreme.AspNet.Data.Helpers { /// A parser for the data processing settings. /// public static class DataSourceLoadOptionsParser { +#if DEBUG + internal +#endif static readonly JsonSerializerOptions DEFAULT_SERIALIZER_OPTIONS = new JsonSerializerOptions(JsonSerializerDefaults.Web) { Converters = { new ListConverter() } };