1

I writing an web API which excepts JSON with references, I am using JsonPropertyAttribute and JsonObjectAttribute to mark properties/classes which can be refereed by some other property. when i am receiving data from API it is working as expected, having corresponding $id and $ref property set in JSON. But when I post same JSON date to API it is not parsing all data back. Bellow is data I am receiving from API and same I am posting back.

{
  "GeneralDetails": {
    "Description": "23",
    "ScheduleInfo": {
        "ScheduleFrequency": 701,
        "ScheduledDay": null,
        "ScheduledMonth": null,
        "ScheduledTime": "2018-04-10T21:30:01"
    },
    "ImagePath": "",
    "BrandId": 23,
    "Name": "23",
    "Id": 29
},
"TargetDetails": {
    "Period": 0,
    "Type": 2701,
    "Targets": [
        {
            "TierId": 34,
            "Value": 29
        }
    ]
},
"PointsDetails": [
    {
        "BooleanExperession": {
            "$id": "1",
            "$type": "Payback.TradeTool.Entities.Model.Offer.OfferRuleBooleanExpression, Payback.TradeTool.Entities",
            "Variable1": {
                "$id": "2",
                "$type": "Payback.TradeTool.Entities.Model.Offer.OfferRulePreDefinedVariable, Payback.TradeTool.Entities",
                "GroupId": 2,
                "Type": 12,
                "AvailableOperant": 289,
                "Description": "Product SKU",
                "Name": "Product SKU",
                "Id": 67
            },
            "Variable2": {
                "$id": "3",
                "$type": "Payback.TradeTool.Entities.Model.Offer.OfferRuleConstant`1[[System.String, mscorlib]], Payback.TradeTool.Entities",
                "Value": "23",
                "Type": 9,
                "AvailableOperant": 289,
                "Description": "2323",
                "Name": "2323",
                "Id": 132
            },
            "Operation": 1,
            "Type": 130,
            "AvailableOperant": 0,
            "Description": "23",
            "Name": "23",
            "Id": 133
        },
        "Value": 23,
        "Id": 16,
        "Type": 0,
        "ValueX": null
    }
],
"Constants": [
    {
        "$id": "4",
        "Value": "rty",
        "Type": 9,
        "AvailableOperant": 289,
        "Description": "rty",
        "Name": "yurt",
        "Id": 130
    },
    {
        "$id": "5",
        "Value": 23,
        "Type": 17,
        "AvailableOperant": 231,
        "Description": "23",
        "Name": "ewe",
        "Id": 131
    },
    {
        "$ref": "3"
    }
],
"BooleanExpressions": [
    {
        "$ref": "1"
    }
],
}

when i am posting back Constants with $id 4 and 5 are not in parsed data. However if I refer them in some other property, then they are also parsing.


EDIT: below is my class structure

public class OfferDetails
{
    public OfferDetails()
    {
        GeneralDetails = new OfferGeneralDetails();
        TargetDetails = new OfferTargetDetails();
        PointsDetails = new List<OfferPointsDetails>();
        Constants = new List<OfferRuleConstant>();
        BooleanExpressions = new List<OfferRuleBooleanExpression>();
        Variables = new Dictionary<string, List<OfferRulePreDefinedVariable>>();
    }
    public OfferGeneralDetails GeneralDetails { get; set; }
    public OfferTargetDetails TargetDetails { get; set; }
    [JsonProperty(ItemTypeNameHandling = TypeNameHandling.All)]
    public List<OfferPointsDetails> PointsDetails { get; set; }
    [JsonProperty(IsReference = false, ItemTypeNameHandling = TypeNameHandling.All)]
    public List<OfferRuleConstant> Constants { get; set; }
    [JsonProperty(ItemTypeNameHandling = TypeNameHandling.All,IsReference = false)]
    public List<OfferRuleBooleanExpression> BooleanExpressions { get; set; }
    public Dictionary<string, List<OfferRulePreDefinedVariable>> Variables { get; set; }
}


[JsonObject(ItemTypeNameHandling = TypeNameHandling.All, IsReference = true)]
public class OfferRuleConstant<T> : OfferRuleConstant
{
    public OfferRuleConstant()
    {
        Type = RuleVariableType.Constant;
    }
    public T Value {  get => (T)_value; set=> _value = value;}
    public override string ToString()
    {
        return Value.ToString();
    }
}
public abstract class OfferRuleConstant : OfferRuleVariable, ISeprateStringReprsentation
{
    protected object _value;

    public string StringReprsentation { get ; set ; }
}

[JsonObject(IsReference = true, ItemTypeNameHandling = TypeNameHandling.All)]
public class OfferRuleVariable : NamedEntity<long>
{
    public OfferRuleVariable()
    {
        Type = RuleVariableType.Variable;
    }
    public RuleVariableType Type { get; set; }
    public RuleOperantEnum AvailableOperant { get; set; }
    public string Description { get; set; }
    // public int GroupId { get; set; }
}
[JsonObject(IsReference = true, ItemTypeNameHandling = TypeNameHandling.All)]
public class OfferRulePreDefinedVariable : OfferRuleVariable
{
    public int GroupId { get; set; }
}
public interface ISeprateStringReprsentation 
{
    string StringReprsentation { get; set; }
}

It is possible that I have made certain changes in model (Added a new Property, in a few class and also have changed some attribute while trying to fix above issue).

so, this is updated JSON I am trying to parse:

{
   "$id":0,
   "GeneralDetails":{
      "$id":1,
      "ScheduleInfo":{
         "$id":2,
         "ScheduleFrequency":701,
         "ScheduledDay":null,
         "ScheduledMonth":null,
         "ScheduledTime":null,
         "ScheduledTimeS":null
      },
      "Name":"tuy",
      "Description":"ty"
   },
   "BooleanExpressions":[
      {
         "$id":3,
         "$type":"Payback.TradeTool.Entities.Model.Offer.OfferRuleBooleanExpression, Payback.TradeTool.Entities",
         "Type":130,
         "Variable1":{
            "$id":4,
            "Id":46,
            "Name":"Transaction DateTime",
            "Type":100,
            "AvailableOperant":55,
            "Description":"Transaction DateTime"
         },
         "Variable2":{
            "$id":5,
            "$type":"Payback.TradeTool.Entities.Model.Offer.OfferRuleConstant`1[[System.DateTime, mscorlib]], Payback.TradeTool.Entities",
            "Type":97,
            "Value":"2018-04-19T10:36:02.000Z",
            "Name":"6",
            "AvailableOperant":7,
            "Description":"6",
            "StringReprsentation":"4/19/2018, 4:06:02 PM"
         },
         "Operation":1,
         "AvailableOperant":224,
         "Name":"tuy",
         "Description":"uy",
         "StringReprsentation":"(Transaction DateTime EqualTo 4/19/2018, 4:06:02 PM)"
      },
      {
         "$id":6,
         "$type":"Payback.TradeTool.Entities.Model.Offer.OfferRuleBooleanExpression, Payback.TradeTool.Entities",
         "Type":130,
         "Variable1":{
            "$id":7,
            "Id":48,
            "Name":"Transaction Month",
            "Type":4100,
            "AvailableOperant":57,
            "Description":"Transaction Month"
         },
         "Variable2":{
            "$id":8,
            "$type":"Payback.TradeTool.Entities.Model.Offer.OfferRuleListConstant`1[[System.Int32, mscorlib]], Payback.TradeTool.Entities",
            "Type":5649,
            "Value":[
               2,
               4,
               3
            ],
            "Name":"13",
            "AvailableOperant":40,
            "Description":"33",
            "StringReprsentation":"February,April,March"
         },
         "Operation":8,
         "AvailableOperant":224,
         "Name":"tyu",
         "Description":"yu",
         "StringReprsentation":"(Transaction Month In February,April,March)"
      }
   ],
   "TargetDetails":{
      "$id":9,
      "Period":701,
      "Type":2701,
      "Targets":[
         {
            "$id":10,
            "TierId":34,
            "Value":1
         },
         {
            "$id":11,
            "TierId":86,
            "Value":2
         },
         {
            "$id":12,
            "TierId":87,
            "Value":3
         },
         {
            "$id":13,
            "TierId":88,
            "Value":4
         }
      ]
   },
   "PointsDetails":[
      {
         "$id":14,
         "BooleanExperession":{
            "$ref":"3"
         },
         "Type":1,
         "Value":45,
         "ValueX":4
      }
   ],
   "Constants":[
      {
         "$id":15,
         "$type":"Payback.TradeTool.Entities.Model.Offer.OfferRuleConstant`1[[System.Int32, mscorlib]], Payback.TradeTool.Entities",
         "Type":17,
         "Value":"8",
         "Name":"8",
         "AvailableOperant":231,
         "Description":"8",
         "StringReprsentation":"8"
      },
      {
         "$id":16,
         "$type":"Payback.TradeTool.Entities.Model.Offer.OfferRuleListConstant`1[[System.Int32, mscorlib]], Payback.TradeTool.Entities",
         "Type":263697,
         "Name":"2",
         "AvailableOperant":40,
         "Value":[
            1201,
            1202
         ],
         "Description":"2",
         "StringReprsentation":"Male,Female"
      },
      {
         "$id":17,
         "Type":1049617,
         "Value":1501,
         "StringReprsentation":"Dealer",
         "$type":"Payback.TradeTool.Entities.Model.Offer.OfferRuleConstant`1[[System.Int32, mscorlib]], Payback.TradeTool.Entities",
         "Description":"2",
         "Name":"1"
      },
      {
         "$ref":"8"
      },
      {
         "$id":18,
         "$type":"Payback.TradeTool.Entities.Model.Offer.OfferRuleRangeConstant`1[[System.Int32, mscorlib]], Payback.TradeTool.Entities",
         "Type":5393,
         "Value":{
            "$id":19,
            "From":1,
            "To":6
         },
         "Name":"12",
         "AvailableOperant":16,
         "Description":"12",
         "StringReprsentation":"January AND June"
      },
      {
         "$id":20,
         "$type":"Payback.TradeTool.Entities.Model.Offer.OfferRuleConstant`1[[System.Int32, mscorlib]], Payback.TradeTool.Entities",
         "Type":5137,
         "Value":2,
         "Name":"11",
         "AvailableOperant":33,
         "Description":"11",
         "StringReprsentation":"February"
      },
      {
         "$id":21,
         "$type":"Payback.TradeTool.Entities.Model.Offer.OfferRuleListConstant`1[[System.Int32, mscorlib]], Payback.TradeTool.Entities",
         "Type":3601,
         "Value":[
            1,
            2,
            3,
            0
         ],
         "Name":"10",
         "AvailableOperant":40,
         "Description":"33",
         "StringReprsentation":"Tuesday,Wednesday,Thursday,Monday"
      },
      {
         "$id":22,
         "$type":"Payback.TradeTool.Entities.Model.Offer.OfferRuleRangeConstant`1[[System.Int32, mscorlib]], Payback.TradeTool.Entities",
         "Type":3345,
         "Value":{
            "$id":23,
            "From":0,
            "To":4
         },
         "Name":"9",
         "AvailableOperant":231,
         "Description":"9",
         "StringReprsentation":"Monday AND Friday"
      },
      {
         "$id":24,
         "$type":"Payback.TradeTool.Entities.Model.Offer.OfferRuleConstant`1[[System.Int32, mscorlib]], Payback.TradeTool.Entities",
         "Type":3089,
         "Value":0,
         "Name":"7",
         "AvailableOperant":225,
         "Description":"7",
         "StringReprsentation":"Monday"
      },
      {
         "$ref":"5"
      },
      {
         "$id":25,
         "$type":"Payback.TradeTool.Entities.Model.Offer.OfferRuleConstant`1[[System.DateTime, mscorlib]], Payback.TradeTool.Entities",
         "Type":33,
         "Value":"2018-04-04T10:36:02.000Z",
         "Name":"5",
         "AvailableOperant":7,
         "Description":"5",
         "StringReprsentation":"4/4/2018"
      },
      {
         "$id":26,
         "$type":"Payback.TradeTool.Entities.Model.Offer.OfferRuleConstant`1[[System.Int32, mscorlib]], Payback.TradeTool.Entities",
         "Type":17,
         "Value":"4",
         "Name":"4",
         "AvailableOperant":231,
         "Description":"4",
         "StringReprsentation":"4"
      },
      {
         "$id":27,
         "$type":"Payback.TradeTool.Entities.Model.Offer.OfferRuleConstant`1[[System.String, mscorlib]], Payback.TradeTool.Entities",
         "Type":9,
         "Name":"3",
         "AvailableOperant":289,
         "Value":"3",
         "Description":"3",
         "StringReprsentation":"3"
      }
   ],
   "Variables":{
      "$id":28
   }
}

most of the Constants are parsing, but corresponding to "$id":17 is not in list.

goyaltushar92
  • 296
  • 1
  • 13
  • We need to see a [mcve] that shows your c# classes to help you. That being said, Is there any chance that `Constants` is a read-only collection or collection with a parameterized constructor? If so see [Cannot preserve reference to array or readonly list, or list created from a non-default constructor](https://stackoverflow.com/q/41293407) or [JSON .Net not respecting PreserveReferencesHandling on Deserialization](https://stackoverflow.com/q/25853407) or [Usage of non-default constructor breaks order of deserialization in Json.net](https://stackoverflow.com/q/36866131). – dbc Apr 11 '18 at 18:09
  • @dbc, I have updated required details. – goyaltushar92 Apr 12 '18 at 11:35
  • I tried testing the code in your edited question, but it doesn't compile -- some types and enums are missing. See https://dotnetfiddle.net/jPm1f4 – dbc Apr 17 '18 at 19:11
  • I have deleted my comment as it was having some typing mistakes, refer answer. for solution. – goyaltushar92 Jun 09 '19 at 07:41

1 Answers1

0

after a few tries, i was able to find my mistake, It was "$id" property in json. which is number but in original JSON generated from API, it was string.

so, i changed my javaScript code generating JSON and it worked. However I was unable to understand why it failed. when i posted with same data as generated form API initially, may be i just got confused.

goyaltushar92
  • 296
  • 1
  • 13