0

Thank you in advance. I am really stuck on this one, but practicing. Thank you in advance for any help.

I am able to successfully build this Json object in my code, but de-serializing it with the same Dictionary I used to build it, is not working because the string type defined is anonymous and I cannot access specifically the sub items (contains, equals, startsWith).

I have my json being built successfully but again, does not work when deserializing it.

{
"shortDescription": {
  "contains": false,
  "equals": false,
  "startsWith": true,
  "value": "some text"
},
"description": {
  "contains": true,
  "equals": false,
  "startsWith": false,
  "value": "some more text"
},
"createdAfter": {
  "contains": false,
  "equals": false,
  "startsWith": false,
  "value": "2021-08-17"
},
"notes": "Something bad happened",
"group": "some group",
"assigned": "to me"
}

These objects like shortDescription may not even exist depending on user selection which I why I built an anonymous type Dictionary using "String" public Dictionary<string, filter_properties> properties { get; set; } I can apply this format to any object that needs these properties.

public class filter_keys
{
    public string notes { get; set; }
    public string group { get; set; }
    public string assigned { get; set; }
    public Dictionary<string, filter_properties> properties { get; set; }
}
public class filter_properties
{
    public bool contains { get; set; }
    public bool equals { get; set; }
    public bool startsWith { get; set; }
    public string value { get; set; }
}

I would really appreciate some help to figure out how to set a simple property only for this description and shortDescription fields, not just to serialize the data but also to de-serialize the data, so I can check if these objects even exist in the json.

When I am setting the json I use

Dictionary<string, filter_properties> keys = new Dictionary<string, filter_properties>();

keys.Add("anonymous", new filter_properties { value="can't find it" });

and/or

keys.Add("shortDescription", new filter_properties { 
                        contains = true, 
                        value = "blah blah blah"
                    });
4
  • 1
    Is your problem that there is a fixed set of possible properties like shortDescription that may not even exist or that the possible set of properties is not known in advance and is unlimited? Commented Aug 18, 2021 at 19:54
  • 1
    Can you elaborate onis not working? Also can you share the code of serialization and deserialization? Commented Aug 18, 2021 at 19:57
  • That dictionary object property is called properties in your POCO class, but in the json, shortDescription, description, and createdAfter are all in the root, not under a properties node. What happens if you reconstruct your json to put those three under a properties node? Commented Aug 18, 2021 at 20:13
  • If your root object has a mixture of fixed properties (such as notes and group) along with a variable set of properties whose values have a fixed schema, here filter_properties, you can use [JsonTypedExtensionData] public Dictionary<string, filter_properties> properties { get; set; } where [JsonTypedExtensionData] and its associated TypedExtensionDataConverter<filter_keys> come from How to deserialize a child object with dynamic (numeric) key names?. Commented Aug 19, 2021 at 0:40

2 Answers 2

1

Like I mention in my comment, you have to build your json with those properties under a properties node.

using System;
using System.Collections.Generic;
using Newtonsoft.Json;

public class Program
{
    public static void Main()
    {
        var inJson = @"{
        ""properties"": {
            ""shortDescription"": {
              ""contains"": false,
              ""equals"": false,
              ""startsWith"": true,
              ""value"": ""some text""
            },
            ""description"": {
              ""contains"": true,
              ""equals"": false,
              ""startsWith"": false,
              ""value"": ""some more text""
            },
            ""createdAfter"": {
              ""contains"": false,
              ""equals"": false,
              ""startsWith"": false,
              ""value"": ""2021-08-17""
            }
        },
        ""notes"": ""Something bad happened"",
        ""group"": ""some group"",
        ""assigned"": ""to me""
        }";
        
        var deserialized = JsonConvert.DeserializeObject<filter_keys>(inJson);
        Console.WriteLine(deserialized.notes);
        foreach(var prop in deserialized.properties)
        {
            Console.WriteLine(prop.Key);
            Console.WriteLine(prop.Value.value);
        }
    }

    public class filter_keys
    {
        public string notes { get; set; }
        public string group { get; set; }
        public string assigned { get; set; }
        public Dictionary<string, filter_properties> properties { get; set; }
    }
    public class filter_properties
    {
        public bool contains { get; set; }
        public bool equals { get; set; }
        public bool startsWith { get; set; }
        public string value { get; set; }
    }
}

See:

https://dotnetfiddle.net/bdGTmf

Sign up to request clarification or add additional context in comments.

Comments

0

I followed your guidance Jonathan, you were right of course. I just added an explicit key for every item instead of using a generic one.

public class filter_keys
{
    public string info { get; set; }
    public string dec { get; set; }
    public string assigned { get; set; }
    public string state { get; set; }
    public string target { get; set; }
    public string caller { get; set; }
    public filter_properties shortDescription { get; set; }
    public filter_properties description { get; set; }
    public filter_properties status { get; set; }
    public DateTime date1 { get; set; }
    public DateTime date2 { get; set; }
    public DateTime date3 { get; set; }
    public DateTime date4 { get; set; }
}
public class filter_properties
{
    public bool contains { get; set; }
    public bool equals { get; set; }
    public bool startsWith { get; set; }
    public bool isNot { get; set; }
    public string _value { get; set; }
}

Implementation

filter_keys keys = new filter_keys();

filter_properties = new filter_properties { 
                            contains = true,
                            _value = descriptionTxt.Text
                    };
keys.description = filter_properties;

Everything serializes and de-serializes great.

string filters = (string)Session["incidentRequest"];

if (!string.IsNullOrEmpty(filters))
{
   // for lates version of newtonsoft.json nulls cause error. Add null value handling
   filter_keys filter_values = JsonConvert.DeserializeObject<filter_keys>(filters, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });

   query += "group=" + filter_values.target;

}

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.