Невозможно обновить существующий список json с помощью jsonconverter

Я пытаюсь добавить поле в JSON при десериализации ответа от сервера, а затем сохранить его в базе данных

вот модель ответа

 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, где я выбираю имя клиента из другого json и сохраняю его в цитате

 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();
        }
    }

вот 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 получил от сервера

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"
  }

ожидаемый 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"
  }

Котировочная модель

 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; }



    }

обновленный

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;
}

вот как называется моя десериализация

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

3 ответа

Решение

Проблема здесь не в десериализации JSON и не в добавлении в массив json, а в том, что у вас нет записи из базы данных.

Вы используете это:

 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 ожидает, что в результате запроса будет возвращено ноль или более элементов, но вы хотите получить доступ только к первому элементу в своем коде (т.е. вы не уверены, существует ли элемент с данным ключом)

Изменить это на First(); и посмотрите, будет ли он выдавать исключение, если это так, то это ваша проблема и ваша:

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

возвращает неверные данные.

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; }
}

Я считаю, что этот метод вашего конвертера неверен

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

objectType в этом случае будет иметь тип IList<Quotation> не JsonConverter<IList<Quotation>>, Я считаю, что это следует читать:

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

редактировать: хотя я действительно считаю, что это неправильно, я больше не верю, что это является основной причиной проблемы. Я воспроизвел проблему точно, и исправление должно было изменить эту линию.

public IList<Quotation> quotationsList { get; }

в

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

JsonConvert необходим общедоступный установщик, чтобы иметь возможность назначать значения свойствам.

Я также изменил эту строку

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

в

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

это говорит вызову DeserializeObject, в какой класс попытаться десериализоваться.

Другие вопросы по тегам