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