diff --git a/net/DevExtreme.AspNet.Data.Tests.Common/DevExtreme.AspNet.Data.Tests.Common.csproj b/net/DevExtreme.AspNet.Data.Tests.Common/DevExtreme.AspNet.Data.Tests.Common.csproj index 345163de..7a31e610 100644 --- a/net/DevExtreme.AspNet.Data.Tests.Common/DevExtreme.AspNet.Data.Tests.Common.csproj +++ b/net/DevExtreme.AspNet.Data.Tests.Common/DevExtreme.AspNet.Data.Tests.Common.csproj @@ -1,7 +1,7 @@ - net452;net6.0 + net461;net6.0 DevExtreme.AspNet.Data.Tests False diff --git a/net/DevExtreme.AspNet.Data.Tests.NET4/DevExtreme.AspNet.Data.Tests.NET4.csproj b/net/DevExtreme.AspNet.Data.Tests.NET4/DevExtreme.AspNet.Data.Tests.NET4.csproj index b996ba11..e05e309e 100644 --- a/net/DevExtreme.AspNet.Data.Tests.NET4/DevExtreme.AspNet.Data.Tests.NET4.csproj +++ b/net/DevExtreme.AspNet.Data.Tests.NET4/DevExtreme.AspNet.Data.Tests.NET4.csproj @@ -4,7 +4,7 @@ net472 DevExtreme.AspNet.Data.Tests DevExtreme.AspNet.Data.Tests - NET4 + NET4;NEWTONSOFT_TESTS @@ -12,7 +12,7 @@ - + diff --git a/net/DevExtreme.AspNet.Data.Tests/CustomFilterCompilersTests.cs b/net/DevExtreme.AspNet.Data.Tests/CustomFilterCompilersTests.cs index 04d8c80d..a9f8c7e8 100644 --- a/net/DevExtreme.AspNet.Data.Tests/CustomFilterCompilersTests.cs +++ b/net/DevExtreme.AspNet.Data.Tests/CustomFilterCompilersTests.cs @@ -1,10 +1,11 @@ using DevExtreme.AspNet.Data.Helpers; -using Newtonsoft.Json; + using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; +using System.Text.Json; using Xunit; namespace DevExtreme.AspNet.Data.Tests { @@ -34,7 +35,8 @@ public void OneToManyContains() { var source = new[] { new Category(), new Category() }; source[0].Products.Add(new Product { Name = "Chai" }); - var filter = JsonConvert.DeserializeObject(@"[ ""Products"", ""Contains"", ""ch"" ]"); + var deserializedList = JsonSerializer.Deserialize(@"[ ""Products"", ""Contains"", ""ch"" ]"); + var filter = Compatibility.UnwrapList(deserializedList); var loadOptions = new SampleLoadOptions { Filter = filter, diff --git a/net/DevExtreme.AspNet.Data.Tests/DataSourceLoadOptionsParserTests.cs b/net/DevExtreme.AspNet.Data.Tests/DataSourceLoadOptionsParserTests.cs index 5f918942..10064cdb 100644 --- a/net/DevExtreme.AspNet.Data.Tests/DataSourceLoadOptionsParserTests.cs +++ b/net/DevExtreme.AspNet.Data.Tests/DataSourceLoadOptionsParserTests.cs @@ -1,8 +1,7 @@ using DevExtreme.AspNet.Data.Helpers; -using System; + using System.Collections.Generic; using System.Linq; -using System.Threading.Tasks; using Xunit; namespace DevExtreme.AspNet.Data.Tests { @@ -60,6 +59,21 @@ public void MustNotParseDates() { Assert.IsType(opts.Filter[1]); } + [Fact] + public void MustParseNumericAsString() { + var opts = new SampleLoadOptions(); + + DataSourceLoadOptionsParser.Parse(opts, key => { + if(key == DataSourceLoadOptionsParser.KEY_GROUP) + return @"[{""selector"":""freight"",""groupInterval"":100,""isExpanded"":false}]"; + return null; + }); + + Assert.Equal("freight", opts.Group[0].Selector); + Assert.Equal("100", opts.Group[0].GroupInterval); + Assert.False(opts.Group[0].IsExpanded); + } + } } diff --git a/net/DevExtreme.AspNet.Data.Tests/DevExtreme.AspNet.Data.Tests.csproj b/net/DevExtreme.AspNet.Data.Tests/DevExtreme.AspNet.Data.Tests.csproj index 73074112..df27a61b 100644 --- a/net/DevExtreme.AspNet.Data.Tests/DevExtreme.AspNet.Data.Tests.csproj +++ b/net/DevExtreme.AspNet.Data.Tests/DevExtreme.AspNet.Data.Tests.csproj @@ -2,6 +2,7 @@ net6.0 + NEWTONSOFT_TESTS diff --git a/net/DevExtreme.AspNet.Data.Tests/DynamicBindingTests.cs b/net/DevExtreme.AspNet.Data.Tests/DynamicBindingTests.cs index 4fbe2123..06a51cce 100644 --- a/net/DevExtreme.AspNet.Data.Tests/DynamicBindingTests.cs +++ b/net/DevExtreme.AspNet.Data.Tests/DynamicBindingTests.cs @@ -1,14 +1,17 @@ using DevExtreme.AspNet.Data.ResponseModel; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; + using System; using System.Collections; using System.Collections.Generic; using System.Dynamic; using System.Linq; -using System.Text; using Xunit; +#if NEWTONSOFT_TESTS +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +#endif + namespace DevExtreme.AspNet.Data.Tests { public class DynamicBindingTests { @@ -70,6 +73,7 @@ public void Filter() { Assert.Equal(2d, expandoResult[0][P1]); } + #if NEWTONSOFT_TESTS [Fact] public void Filter_JValueNull() { var result = ToDictArray(DataSourceLoader.Load( @@ -83,6 +87,7 @@ public void Filter_JValueNull() { Assert.Single(result); } + #endif [Fact] public void Filter_Null() { @@ -147,6 +152,7 @@ public void Grouping() { Assert.Equal(4m, expandoResult[1].summary[0]); } + #if NEWTONSOFT_TESTS [Fact] public void JArray() { var sourceData = JsonConvert.DeserializeObject(@"[ @@ -167,6 +173,7 @@ public void JArray() { Assert.Equal(4m, result.summary[0]); } + #endif [Fact] public void T598818() { @@ -213,6 +220,7 @@ public void Issue227() { Assert.Single(loadResult.data); } + #if NEWTONSOFT_TESTS [Fact] public void NoToStringForNumbers() { var compiler = new FilterExpressionCompiler(typeof(object), false); @@ -229,6 +237,7 @@ void Case(IList clientFilter, string expectedExpr, object trueTestValue) { 10 ); } + #endif [Fact] public void T714342() { diff --git a/net/DevExtreme.AspNet.Data.Tests/FilterExpressionCompilerTests.cs b/net/DevExtreme.AspNet.Data.Tests/FilterExpressionCompilerTests.cs index 69a67282..0bf12fe3 100644 --- a/net/DevExtreme.AspNet.Data.Tests/FilterExpressionCompilerTests.cs +++ b/net/DevExtreme.AspNet.Data.Tests/FilterExpressionCompilerTests.cs @@ -1,10 +1,9 @@ -using Newtonsoft.Json; -using System; +using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; -using System.Threading.Tasks; +using System.Text.Json; using Xunit; namespace DevExtreme.AspNet.Data.Tests { @@ -144,7 +143,8 @@ public void Not() { [Fact] public void IsUnaryWithJsonCriteria() { - var crit = JsonConvert.DeserializeObject("[\"!\", []]"); + var deserializedList = JsonSerializer.Deserialize("[\"!\", []]"); + var crit = Compatibility.UnwrapList(deserializedList); var compiler = new FilterExpressionCompiler(typeof(object), false); Assert.True(compiler.IsUnary(crit)); } @@ -241,7 +241,8 @@ public void T105740() { [Fact] public void JsonObjects() { - var crit = (IList)JsonConvert.DeserializeObject(@"[ [ ""StringProp"", ""abc"" ], [ ""NullableProp"", null ] ]"); + var deserializedList = JsonSerializer.Deserialize(@"[ [ ""StringProp"", ""abc"" ], [ ""NullableProp"", null ] ]"); + var crit = Compatibility.UnwrapList(deserializedList); var expr = Compile(crit); Assert.Equal(@"((obj.StringProp == ""abc"") AndAlso (obj.NullableProp == null))", expr.Body.ToString()); } diff --git a/net/DevExtreme.AspNet.Data.Tests/FilterExpressionCompilerTypeConversionTests.cs b/net/DevExtreme.AspNet.Data.Tests/FilterExpressionCompilerTypeConversionTests.cs index bb1fbe6b..37d1c80d 100644 --- a/net/DevExtreme.AspNet.Data.Tests/FilterExpressionCompilerTypeConversionTests.cs +++ b/net/DevExtreme.AspNet.Data.Tests/FilterExpressionCompilerTypeConversionTests.cs @@ -1,11 +1,11 @@ -using Newtonsoft.Json; -using System; -using System.Collections; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; +using System; using Xunit; +#if NEWTONSOFT_TESTS +using System.Collections; +using Newtonsoft.Json; +#endif + namespace DevExtreme.AspNet.Data.Tests { public class FilterExpressionCompilerTypeConversionTests { @@ -225,11 +225,15 @@ public void StringFuncOnTimeSpan() { AssertEvaluation(obj, new[] { "NullableTime", "contains", "23" }); } + #if NEWTONSOFT_TESTS [Theory] [InlineData(DateParseHandling.None)] [InlineData(DateParseHandling.DateTime)] [InlineData(DateParseHandling.DateTimeOffset)] public void Issue477(DateParseHandling dateParseHandling) { + //https://github.com/DevExpress/DevExtreme.AspNet.Data/pull/478 + //https://github.com/DevExpress/DevExtreme.AspNet.Data/issues/477 + var date = new DateTimeOffset(2021, 1, 1, 0, 0, 0, TimeSpan.Zero); var filterJSON = JsonConvert.SerializeObject(new object[] { "this", date }); var deserializedFilter = JsonConvert.DeserializeObject(filterJSON, new JsonSerializerSettings { @@ -243,6 +247,7 @@ public void Issue477(DateParseHandling dateParseHandling) { var loadResult = DataSourceLoader.Load(new[] { date }, loadOptions); Assert.Single(loadResult.data); } + #endif } } diff --git a/net/DevExtreme.AspNet.Data.Tests/GroupHelperTests.cs b/net/DevExtreme.AspNet.Data.Tests/GroupHelperTests.cs index 9c023527..3d8987b1 100644 --- a/net/DevExtreme.AspNet.Data.Tests/GroupHelperTests.cs +++ b/net/DevExtreme.AspNet.Data.Tests/GroupHelperTests.cs @@ -1,10 +1,7 @@ using DevExtreme.AspNet.Data.Helpers; using DevExtreme.AspNet.Data.ResponseModel; -using Newtonsoft.Json; using System; using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; using Xunit; namespace DevExtreme.AspNet.Data.Tests { diff --git a/net/DevExtreme.AspNet.Data.Tests/PaginateViaPrimaryKeyTests.cs b/net/DevExtreme.AspNet.Data.Tests/PaginateViaPrimaryKeyTests.cs index 83a780c7..374fd587 100644 --- a/net/DevExtreme.AspNet.Data.Tests/PaginateViaPrimaryKeyTests.cs +++ b/net/DevExtreme.AspNet.Data.Tests/PaginateViaPrimaryKeyTests.cs @@ -1,6 +1,6 @@ -using Newtonsoft.Json; -using System; +using System; using System.Linq; +using System.Text.Json; using Xunit; namespace DevExtreme.AspNet.Data.Tests { @@ -133,7 +133,7 @@ public void Bug349() { } static string DataToString(object data) { - return JsonConvert.SerializeObject(data).Replace("\"", ""); + return JsonSerializer.Serialize(data).Replace("\"", ""); } } diff --git a/net/DevExtreme.AspNet.Data.Tests/ResponseModelExTests.cs b/net/DevExtreme.AspNet.Data.Tests/ResponseModelExTests.cs new file mode 100644 index 00000000..f5eaa134 --- /dev/null +++ b/net/DevExtreme.AspNet.Data.Tests/ResponseModelExTests.cs @@ -0,0 +1,33 @@ +#if NEWTONSOFT_TESTS +using DevExtreme.AspNet.Data.ResponseModel; + +using System.ComponentModel; +using Xunit; + +using Newtonsoft.Json; + +namespace DevExtreme.AspNet.Data.Tests { + + public class ResponseModelTestsEx { + + class LoadResultEx : LoadResult { + [DefaultValue(-1), JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public new int totalCount { get; set; } = -1; + [DefaultValue(-1), JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public new int groupCount { get; set; } = -1; + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public new object[] summary { get; set; } + } + + [Fact] + public void EmptyLoadResultSerialization() { + Assert.Equal( + "{\"data\":null}", + JsonConvert.SerializeObject(new LoadResultEx()) + ); + } + + } + +} +#endif diff --git a/net/DevExtreme.AspNet.Data.Tests/ResponseModelTests.cs b/net/DevExtreme.AspNet.Data.Tests/ResponseModelTests.cs index 647be90a..aaf26dca 100644 --- a/net/DevExtreme.AspNet.Data.Tests/ResponseModelTests.cs +++ b/net/DevExtreme.AspNet.Data.Tests/ResponseModelTests.cs @@ -1,25 +1,25 @@ using DevExtreme.AspNet.Data.ResponseModel; -using Newtonsoft.Json; -using System; -using System.Collections.Generic; -using System.Text; + +using System.Text.Json; using Xunit; namespace DevExtreme.AspNet.Data.Tests { public class ResponseModelTests { - [Fact] + [Fact(Skip = "Skip until consolidation or target bump to net7 and ShouldSerialize")] public void EmptyLoadResultSerialization() { + //https://github.com/dotnet/runtime/issues/41630 + //https://github.com/dotnet/runtime/issues/36236 Assert.Equal( - "{\"data\":null}", - JsonConvert.SerializeObject(new LoadResult()) + "{\"data\":null,\"totalCount\":-1,\"groupCount\":-1}", + JsonSerializer.Serialize(new LoadResult()) ); } [Fact] public void EmptyGroupSerialization() { - var json = JsonConvert.SerializeObject(new Group()); + var json = JsonSerializer.Serialize(new Group()); // these must always be present Assert.Contains("\"key\":", json); diff --git a/net/DevExtreme.AspNet.Data/Compatibility.cs b/net/DevExtreme.AspNet.Data/Compatibility.cs new file mode 100644 index 00000000..0040b3d5 --- /dev/null +++ b/net/DevExtreme.AspNet.Data/Compatibility.cs @@ -0,0 +1,70 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; + +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace DevExtreme.AspNet.Data { + + static class Compatibility { + public static IList UnwrapList(IList deserializedList) { + var unwrappedList = new List(); + foreach(var item in deserializedList) + unwrappedList.Add(UnwrapJsonElement(item)); + return unwrappedList; + } + + static object UnwrapJsonElement(object deserializeObject) { + if(!(deserializeObject is JsonElement jsonElement)) + throw new InvalidOperationException(); + + switch(jsonElement.ValueKind) { + case JsonValueKind.Array: + return jsonElement.EnumerateArray().Select(item => UnwrapJsonElement(item)).ToList(); + case JsonValueKind.String: + return jsonElement.GetString(); + case JsonValueKind.Null: + return null; + case JsonValueKind.False: + case JsonValueKind.True: + return jsonElement.GetBoolean(); + case JsonValueKind.Number: + //same as IsIntegralType + unsigned? + if(jsonElement.TryGetInt32(out var intValue)) + return intValue; + //or floating point as well? + //we primarily use Convert.ToDecimal everywhere + if(jsonElement.TryGetDecimal(out var decimalValue)) + return decimalValue; + throw new NotImplementedException(); + default: + throw new NotImplementedException(); + } + } + } + + class NumericAndStringConverter : JsonConverter { + public override string Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { + if(reader.TokenType == JsonTokenType.Number) + return string.Format(CultureInfo.InvariantCulture, "{0}", GetNumber(ref reader)); + return reader.GetString(); + } + + static object GetNumber(ref Utf8JsonReader reader) { + if(reader.TryGetInt32(out int intValue)) + return intValue; + if(reader.TryGetDecimal(out decimal decimalValue)) + return decimalValue; + throw new NotImplementedException(); + } + + public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options) { + throw new NotImplementedException(); + } + + } + +} diff --git a/net/DevExtreme.AspNet.Data/DevExtreme.AspNet.Data.csproj b/net/DevExtreme.AspNet.Data/DevExtreme.AspNet.Data.csproj index f047ca60..2727b64c 100644 --- a/net/DevExtreme.AspNet.Data/DevExtreme.AspNet.Data.csproj +++ b/net/DevExtreme.AspNet.Data/DevExtreme.AspNet.Data.csproj @@ -14,17 +14,13 @@ DevExtreme.AspNet.Data 99.0 - net452;net6.0 + net461;net6.0 full bin\Debug\$(TargetFramework)\DevExtreme.AspNet.Data.xml 1591 - - - - - + @@ -32,6 +28,10 @@ + + + + diff --git a/net/DevExtreme.AspNet.Data/GroupingInfo.cs b/net/DevExtreme.AspNet.Data/GroupingInfo.cs index 14edd43f..7161d067 100644 --- a/net/DevExtreme.AspNet.Data/GroupingInfo.cs +++ b/net/DevExtreme.AspNet.Data/GroupingInfo.cs @@ -1,7 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; +using System.Text.Json.Serialization; namespace DevExtreme.AspNet.Data { @@ -12,6 +9,7 @@ public class GroupingInfo : SortingInfo { /// /// A value that groups data in ranges of a given length or date/time period. /// + [JsonConverter(typeof(NumericAndStringConverter))] public string GroupInterval { get; set; } /// diff --git a/net/DevExtreme.AspNet.Data/Helpers/DataSourceLoadOptionsParser.cs b/net/DevExtreme.AspNet.Data/Helpers/DataSourceLoadOptionsParser.cs index e9aef280..8dbd5554 100644 --- a/net/DevExtreme.AspNet.Data/Helpers/DataSourceLoadOptionsParser.cs +++ b/net/DevExtreme.AspNet.Data/Helpers/DataSourceLoadOptionsParser.cs @@ -1,10 +1,6 @@ -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; -using System; +using System; using System.Collections; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; +using System.Text.Json; namespace DevExtreme.AspNet.Data.Helpers { @@ -12,6 +8,8 @@ namespace DevExtreme.AspNet.Data.Helpers { /// A parser for the data processing settings. /// public static class DataSourceLoadOptionsParser { + static readonly JsonSerializerOptions DEFAULT_SERIALIZER_OPTIONS = new JsonSerializerOptions(JsonSerializerDefaults.Web); + public const string KEY_REQUIRE_TOTAL_COUNT = "requireTotalCount", KEY_REQUIRE_GROUP_COUNT = "requireGroupCount", @@ -59,25 +57,24 @@ public static void Parse(DataSourceLoadOptionsBase loadOptions, Func(sort); + loadOptions.Sort = JsonSerializer.Deserialize(sort, DEFAULT_SERIALIZER_OPTIONS); if(!String.IsNullOrEmpty(group)) - loadOptions.Group = JsonConvert.DeserializeObject(group); + loadOptions.Group = JsonSerializer.Deserialize(group, DEFAULT_SERIALIZER_OPTIONS); if(!String.IsNullOrEmpty(filter)) { - loadOptions.Filter = JsonConvert.DeserializeObject(filter, new JsonSerializerSettings { - DateParseHandling = DateParseHandling.None - }); + var deserializedList = JsonSerializer.Deserialize(filter); + loadOptions.Filter = Compatibility.UnwrapList(deserializedList); } if(!String.IsNullOrEmpty(totalSummary)) - loadOptions.TotalSummary = JsonConvert.DeserializeObject(totalSummary); + loadOptions.TotalSummary = JsonSerializer.Deserialize(totalSummary, DEFAULT_SERIALIZER_OPTIONS); if(!String.IsNullOrEmpty(groupSummary)) - loadOptions.GroupSummary = JsonConvert.DeserializeObject(groupSummary); + loadOptions.GroupSummary = JsonSerializer.Deserialize(groupSummary, DEFAULT_SERIALIZER_OPTIONS); if(!String.IsNullOrEmpty(select)) - loadOptions.Select = JsonConvert.DeserializeObject(select); + loadOptions.Select = JsonSerializer.Deserialize(select); } } diff --git a/net/DevExtreme.AspNet.Data/ResponseModel/Group.cs b/net/DevExtreme.AspNet.Data/ResponseModel/Group.cs index ad974550..cd396222 100644 --- a/net/DevExtreme.AspNet.Data/ResponseModel/Group.cs +++ b/net/DevExtreme.AspNet.Data/ResponseModel/Group.cs @@ -1,8 +1,5 @@ -using Newtonsoft.Json; -using System; -using System.Collections; -using System.Linq; -using System.Threading.Tasks; +using System.Collections; +using System.Text.Json.Serialization; namespace DevExtreme.AspNet.Data.ResponseModel { @@ -23,13 +20,13 @@ public class Group { /// /// The count of items in the group. /// - [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] public int? count { get; set; } /// /// Group summary calculation results. /// - [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] public object[] summary { get; set; } } diff --git a/net/DevExtreme.AspNet.Data/ResponseModel/LoadResult.cs b/net/DevExtreme.AspNet.Data/ResponseModel/LoadResult.cs index aff75c50..f59e79f2 100644 --- a/net/DevExtreme.AspNet.Data/ResponseModel/LoadResult.cs +++ b/net/DevExtreme.AspNet.Data/ResponseModel/LoadResult.cs @@ -1,10 +1,6 @@ -using Newtonsoft.Json; -using System; -using System.Collections; -using System.Collections.Generic; +using System.Collections; using System.ComponentModel; -using System.Linq; -using System.Threading.Tasks; +using System.Text.Json.Serialization; namespace DevExtreme.AspNet.Data.ResponseModel { @@ -20,19 +16,19 @@ public class LoadResult { /// /// The total number of data objects in the resulting dataset. /// - [DefaultValue(-1), JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + [DefaultValue(-1)/*, JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)*/] public int totalCount { get; set; } = -1; /// /// The number of top-level groups in the resulting dataset. /// - [DefaultValue(-1), JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + [DefaultValue(-1)/*, JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)*/] public int groupCount { get; set; } = -1; /// /// Total summary calculation results. /// - [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] public object[] summary { get; set; } } diff --git a/net/DevExtreme.AspNet.Data/Utils.cs b/net/DevExtreme.AspNet.Data/Utils.cs index e2c949c4..c24c70d0 100644 --- a/net/DevExtreme.AspNet.Data/Utils.cs +++ b/net/DevExtreme.AspNet.Data/Utils.cs @@ -1,11 +1,9 @@ using System; using System.Collections.Generic; +using System.ComponentModel; +using System.Globalization; using System.Linq; -using System.Threading.Tasks; using System.Reflection; -using System.Globalization; -using System.ComponentModel; -using Newtonsoft.Json.Linq; namespace DevExtreme.AspNet.Data { @@ -118,9 +116,11 @@ public static int DynamicCompare(object selectorResult, object clientValue, bool } public static object UnwrapNewtonsoftValue(object value) { - if(value is JValue jValue) - return jValue.Value; - + if(value != null) { + var type = value.GetType(); + if(type.FullName.Equals("Newtonsoft.Json.Linq.JValue")) + return type.GetProperty("Value").GetValue(value, null); + } return value; } diff --git a/net/Sample/Controllers/NorthwindController.cs b/net/Sample/Controllers/NorthwindController.cs index f22cdea9..078968a5 100644 --- a/net/Sample/Controllers/NorthwindController.cs +++ b/net/Sample/Controllers/NorthwindController.cs @@ -1,13 +1,14 @@ -using System; -using System.Collections.Generic; +using DevExtreme.AspNet.Data; + +using Sample.Models; using System.Linq; using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; -using Sample.Models; -using DevExtreme.AspNet.Data; -using Newtonsoft.Json; using Microsoft.EntityFrameworkCore; +using Newtonsoft.Json; + namespace Sample.Controllers { [Route("nwind")] @@ -93,6 +94,7 @@ public async Task UpdateOrder(int key, string values) { [HttpPost("insert-order")] public async Task InsertOrder(string values) { var order = new Order(); + JsonConvert.PopulateObject(values, order); if(!TryValidateModel(order)) diff --git a/net/Sample/DataSourceLoadOptions.cs b/net/Sample/DataSourceLoadOptions.cs index f88d56d9..0c41477b 100644 --- a/net/Sample/DataSourceLoadOptions.cs +++ b/net/Sample/DataSourceLoadOptions.cs @@ -2,10 +2,6 @@ using DevExtreme.AspNet.Data.Helpers; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.ModelBinding; -using Newtonsoft.Json; -using System; -using System.Collections; -using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; diff --git a/net/Sample/Sample.csproj b/net/Sample/Sample.csproj index e9168b07..6cc8e548 100644 --- a/net/Sample/Sample.csproj +++ b/net/Sample/Sample.csproj @@ -8,6 +8,7 @@ +