Share via

Hwo to deserialize jqgrid filter in .NET 5

Andrus 121 Reputation points
2021-06-26T16:56:49.293+00:00

jqgrid filter deserialization in ASP.NET 5 MVC application fails using System.Text.Json.JsonSerializer

To reproduce, run the code

var _filters ="{\"groupOp\":\"AND\",\"rules\":[{\"field\":\"Toode\",\"op\":\"cn\",\"data\":\"\"}]}";

var filtersList = JsonSerializer.Deserialize<Filter>(_filters, new JsonSerializerOptions
                { 
                    PropertyNameCaseInsensitive = true
                });

Result:

The JSON value could not be converted to MyApp.Controllers.GroupOp. Path: $.groupOp | LineNumber: 0 | BytePositionInLine: 16.


System.Text.Json.JsonException: The JSON value could not be converted to MyApp.Controllers.GroupOp. Path: $.groupOp | LineNumber: 0 | BytePositionInLine: 16.
   at System.Text.Json.ThrowHelper.ThrowJsonException(String message)
   at System.Text.Json.Serialization.Converters.EnumConverter`1.Read(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options)
   at System.Text.Json.JsonPropertyInfo`1.ReadJsonAndSetMember(Object obj, ReadStack& state, Utf8JsonReader& reader)
   at System.Text.Json.Serialization.Converters.ObjectDefaultConverter`1.OnTryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value)
   at System.Text.Json.Serialization.JsonConverter`1.TryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value)
   at System.Text.Json.Serialization.JsonConverter`1.ReadCore(Utf8JsonReader& reader, JsonSerializerOptions options, ReadStack& state)
   at System.Text.Json.JsonSerializer.ReadCore[TValue](JsonConverter jsonConverter, Utf8JsonReader& reader, JsonSerializerOptions options, ReadStack& state)
   at System.Text.Json.JsonSerializer.ReadCore[TValue](Utf8JsonReader& reader, Type returnType, JsonSerializerOptions options)
   at System.Text.Json.JsonSerializer.Deserialize[TValue](String json, Type returnType, JsonSerializerOptions options)
   at System.Text.Json.JsonSerializer.Deserialize[TValue](String json, JsonSerializerOptions options)

jqgrid classes used in deserialization:

public class Filter
{
    public GroupOp GroupOp { get; set; }
    public List<Rule> Rules { get; set; }
    public List<Filter> Groups { get; set; }
}

public enum GroupOp
{
    AND,
    OR
}

public class Rule
{
    public string Field { get; set; }
    public Operations Op { get; set; }
    public string Data { get; set; }
}

public enum Operations
{
    eq,
    ne,
    cn,
    le
}

In .NET 4.6 it worked using

var serializer = new JavaScriptSerializer();
var filtersList = serializer.Deserialize<Filter>(_filters);

How to make it work in .NET 5 ?

Developer technologies | ASP.NET Core | Other
0 comments No comments

Answer accepted by question author

Anonymous
2021-06-28T07:27:53.62+00:00

Hi @Andrus ,

For numeric properties jqgrid passes data property values as numbers like:

"{\"groupOp\":\"AND\",\"rules\":[{\"field\":\"Baas\",\"op\":\"eq\",\"data\":\"TDESKTOP\"},{\"field\":\"Liigid\",\"op\":\"eq\",\"data\":\"\"},{\"field\":\"Layoutnumb\",\"op\":\"eq\",\"data\":0}]}"

Trying to deserialize this causes exception

Cannot get the value of a token type 'Number' as a string.
The JSON value could not be converted to System.String. Path: $.rules[2].data | LineNumber: 0 | BytePositionInLine: 150.

The new issue relates this item: {\"field\":\"Layoutnumb\",\"op\":\"eq\",\"data\":0}.

For the data property, it is string type, but in the JSON string, this item is Number type, so it will cause this issue.

To solve this issue, you could change the 0 to \"0\", the updated JSON string as below:

"{\"groupOp\":\"AND\",\"rules\":[{\"field\":\"Baas\",\"op\":\"eq\",\"data\":\"TDESKTOP\"},{\"field\":\"Liigid\",\"op\":\"eq\",\"data\":\"\"},{\"field\":\"Layoutnumb\",\"op\":\"eq\",\"data\":\"0\"}]}".

Besides, you could also use Regex to replace the number value to string:

var _filters = "the new json string";  

string pattern = @"(?<![""\w])(\d)(?![""\w])";    
var result = Regex.Replace(_filters, pattern, "\"$1\"");              

The result like this:

109778-3.gif


If the answer is helpful, please click "Accept Answer" and upvote it.
Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

Best Regards,
Dillion

Was this answer helpful?

0 comments No comments

2 additional answers

Sort by: Most helpful
  1. Anonymous
    2021-06-28T02:58:57.683+00:00

    Hi @Andrus ,

    Since the JSON string and Model contains Enum data type, when deserialize the json string, you should add the JsonStringEnumConverter.

    Try to use the following code:

    var _filters = "{\"groupOp\":\"AND\",\"rules\":[{\"field\":\"Toode\",\"op\":\"cn\",\"data\":\"\"}]}";  
    
    //using System.Text.Json;  
    //using System.Text.Json.Serialization;  
    var options = new JsonSerializerOptions();  
    options.PropertyNameCaseInsensitive = true;  
    options.Converters.Add(new JsonStringEnumConverter());  
               
    var filtersList = JsonSerializer.Deserialize<Filter>(_filters, options);  
    

    Then, the result as below:

    109649-capture.png


    If the answer is helpful, please click "Accept Answer" and upvote it.
    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    Best Regards,
    Dillion

    Was this answer helpful?


  2. Ken Tucker 5,866 Reputation points
    2021-06-26T18:15:14.82+00:00

    Looks like you have a circular reference in the Filter class. Try something like this

            JsonSerializerOptions options = new()  
            {  
                ReferenceHandler = ReferenceHandler.Preserve,  
                WriteIndented = true  
            };  
    
            var filtersList = serializer.Deserialize<Filter>(_filters, options);  
    

    https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-preserve-references?pivots=dotnet-5-0

    Was this answer helpful?


Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.