Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

unable to update existing json list using jsonconverter

Tags:

c#

json.net

realm

i am trying to add field in json while deserializing the response from server and then storing it into database

here is the model of Response

 public class Response : RealmObject
    {

        [JsonConverter(typeof(QuotationConverter))]
        [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
        public IList<Quotation> quotationsList { get; }

        [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
        public IList<Order> ordersList { get; }
    }

QuotationConverter code where i am fetching customer name from another json and store it into quotation

 protected override IList<Quotation> parseArray(Type objectType, JArray jsonArray)
        {

            try
            {
                Realm realm = Realm.GetInstance();
                foreach (JObject data in jsonArray)
                {

                    String customerId = data.GetValue("customerId").ToString();
                    Customer customer = realm.All<Customer>().Where(c => c.customerId == Java.Lang.Long.ParseLong(customerId)).FirstOrDefault();
                    if (customer != null)
                    {
                        String customerName = customer.customerName;
                        data.Add("customerName", customerName);
                    }

                }

                realm.Dispose();
                var quotationsList = jsonArray.ToObject<IList<Quotation>>();

                List<Quotation> quotation = new List<Quotation>(quotationsList);

                return quotationsList;
            }
            catch(Exception e)
            {

                Debug.WriteLine(" exception "+e.StackTrace);
            }

            return null;
        }

        protected override Quotation parseObject(Type objectType, JObject jsonObject)
        {
            throw new NotImplementedException();
        }
    }

here is the JsonConverter

 public abstract class JsonConverter<T> : Newtonsoft.Json.JsonConverter
    {
        public override bool CanConvert(Type objectType)
        {
            return (objectType == typeof(JsonConverter<T>));

        }

        protected abstract T parseObject(Type objectType, JObject jsonObject);

        protected abstract IList<T> parseArray(Type objectType, JArray jsonArray);
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {

            try
            {              
               var jsonArray = JArray.Load(reader);
               var data=  parseArray(objectType, jsonArray);              
               return data;

            }
            catch(Exception e)
            {
                Debug.WriteLine(e.StackTrace);
            }
            return null;

        }

        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {

            Debug.WriteLine("Mo " + value);


        }
    }

the issue is when i am getting Response object inside that quotationsList is coming blank.

Json received from server

quotationsList: [
  {
    "account": null,
    "contactId": 0,
    "currency": "USD",
    "customerId": 5637144583,
    "deliveryAddress": "19TH and Edwardsville RD (RT203)\nGranite City,IL62040\nUSA",
    "expiryDate": "2017-09-04",
    "followUpDate": "2017-09-01",
    "mQuotationId": null,
    "opportunityId": 0,
    "postedOn": null,
    "prospectId": 0,
    "quotationFor": null,
    "quotationId": 5637155076,
    "quotationName": "United States Steel",
    "quotationNumber": "UST1-000022",
    "quotationStatus": "Confirmed",
    "requestReceiptDate": "2017-08-05",
    "requestShipDate": "2017-08-05",
    "siteId": "GLEN1",
    "wareHouseId": "37"
  }

expected json

quotationsList: [
  {
    "account": null,
    "contactId": 0,
    "currency": "USD",
    "customerId": 5637144583,
    "deliveryAddress": "19TH and Edwardsville RD (RT203)\nGranite City,IL62040\nUSA",
    "expiryDate": "2017-09-04",
    "followUpDate": "2017-09-01",
    "mQuotationId": null,
    "opportunityId": 0,
    "postedOn": null,
    "prospectId": 0,
    "quotationFor": null,
    "quotationId": 5637155076,
    "quotationName": "United States Steel",
    "quotationNumber": "UST1-000022",
    "quotationStatus": "Confirmed",
    "requestReceiptDate": "2017-08-05",
    "requestShipDate": "2017-08-05",
    "siteId": "GLEN1",
    "wareHouseId": "37",
    "customerName":"Jhon Caro"
  }

Quotation model

 public class Quotation : RealmObject , IMaster, IMedia, IProduct
    {
        [PrimaryKey]
        [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
        public String mQuotationId { get; set; } = Guid.NewGuid().ToString();

        [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
        public long quotationId { get; set; }

        [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
        public String customerName { get; set; }

        [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
        public string quotationName { get; set; }

        [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
        public string quotationNumber{ get; set; }

        [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
        public string deliveryAddress { get; set; }

        [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
        public string expiryDate { get; set; }

        [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
        public string requestShipDate { get; set; }

        [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
        public string requestReceiptDate { get; set; }

        [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
        public long prospectId { get; set; }

        [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
        public string followUpDate { get; set; }

        [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
        public long opportunityId { get; set; }

        [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
        public string postedOn { get; set; }



    }

updated

protected override IList<Quotation> parseArray(Type objectType, JArray jsonArray)
{

    try
    {
        Realm realm = Realm.GetInstance();
        var data = jsonArray.ToObject<IList<Quotation>>();
        List<Quotation> quotationList = new List<Quotation>(data);



        foreach (Quotation quotation in quotationList)
        {

            long customerId = quotation.customerId;
            Customer customer = realm.All<Customer>().Where(c => c.customerId == customerId).FirstOrDefault();
            if (customer != null)
            {
                String customerName = customer.customerName;
                quotation.customerName = customerName;
            }

        }

        realm.Dispose();


        return quotationList;
    }
    catch(Exception e)
    {

        Debug.WriteLine(" exception "+e.StackTrace);
    }

    return null;
}

enter image description here

this is how my deserialize get called

Response responseData = await Task.Run(() => JsonConvert.DeserializeObject(content));

like image 926
Hunt Avatar asked Aug 21 '17 11:08

Hunt


3 Answers

The issue here is not the JSON Deserialize or the add to the json array, the issue it that you have no record coming from the DataBase.

You are using this:

 long customerId = quotation.customerId;
            Customer customer = realm.All<Customer>().Where(c => c.customerId == customerId).FirstOrDefault();
            if (customer != null)
            {
                String customerName = customer.customerName;
                quotation.customerName = customerName;
            }

FirstOrDefault will expect zero or more items to be returned by a query but you only want to access the first item in your code (i.e. you are not sure if an item with a given key exists)

Change this to First(); and see if it throws and exception, if it does then this is your issue and your:

realm.All<Customer>().Where(c => c.customerId == customerId)

is returning incorrect data.

like image 122
Barr J Avatar answered Nov 14 '22 09:11

Barr J


public class Response : RealmObject
{
    //JsonConverter attribute should be decorating 'Quotation' class
    //[JsonConverter(typeof(QuotationConverter))]
    [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
    public IList<Quotation> quotationsList { get; }

    [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
    public IList<Order> ordersList { get; }
}
like image 20
Gurpreet Avatar answered Nov 14 '22 09:11

Gurpreet


I believe this method of your converter is incorrect

public override bool CanConvert(Type objectType)
{
    return (objectType == typeof(JsonConverter<T>));
}

objectType in this case would be of type IList<Quotation> not JsonConverter<IList<Quotation>>. I believe this should read:

public override bool CanConvert(Type objectType)
{
    return (objectType == typeof(T));
}

edit: While I do believe this is incorrect I no longer believe it is the root cause of the problem. I have reproduced the problem exactly and the fix was to change this line.

public IList<Quotation> quotationsList { get; }

to

public IList<Quotation> quotationsList { get; set; }

JsonConvert needs a public setter in order to be able to assign values to properties.

I also changed this line

Response responseData = await Task.Run(() => JsonConvert.DeserializeObject(content));

to

Response responseData = await Task.Run(() => JsonConvert.DeserializeObject<Response>(content));

this tells DeserializeObject call which class to try and deserialize into.

like image 45
Aaron Roberts Avatar answered Nov 14 '22 10:11

Aaron Roberts