2017-08-21 48 views
9

próbuję dodać pole w json podczas deserializacji odpowiedź od serwera, a następnie przechowywanie go w baziestanie zaktualizować istniejącą listę json używając jsonconverter

oto model Response Code

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 gdzie jestem pobierania nazwy klienta z innego json i przechowywać go w cytacie

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

oto 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 otrzymanych od serwera

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

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

modelu Wyznaczona

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



    } 

zaktualizowanej

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

to jak moja Cofnięcie się nazywa

Response responseData = czekają Task.Run (() => JsonConvert.DeserializeObject (zawartość));

+0

Różnica to na końcu pole 'customerName', dodaję je jako nowe pole – Hunt

+0

Czy możesz nam powiedzieć, dlaczego robisz kod w taki sposób, w jaki robisz, zamiast ustawiać właściwość' customerName' w 'Notowaniu' po tym wierszu 'List quotation = new List (quotationsList);'? – mjwills

+0

'quotationsList' ma tak wiele rekordów i dodaję' customerName' dla wszystkich pozycji listowych w 'quotationsList', więc gdy już otrzymam notowania, Listopis przygotowałem, tworzę nową Listę i odeślę ją. – Hunt

Odpowiedz

2

Kwestia tutaj nie jest JSON Deserialize lub dodać do tablicy json, problem, że nie masz rekordu pochodzącego z DataBase.

Używasz tego:

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 będą oczekiwać zero lub więcej elementów, które mają być zwracane przez kwerendy, ale chcesz tylko dostęp do pierwszego elementu w kodzie (czyli nie jesteś pewien, czy element o danym kluczu istnieje)

zmienić na First(); i sprawdzić, czy i rzuca wyjątek, jeśli tak to jest to problem i waszym

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

zwraca niepoprawne dane.

+0

po prostu modyfikuję jedno pole, tj. Nazwę klienta w ofercie, jeśli nazwa klienta istnieje, przypiszę to do nazwy klienta cudzysłowu, czy pozostanie on taki, jaki jest. więc nie jest konieczne, aby każdy identyfikator klienta istniał w tabeli klienta, dlatego użyłem pierwszej lub domyślnej wartości, a gdy nazwa klienta nie istnieje, nazwa klienta będzie miała wartość null, nie widzę nic w tym kodzie. Próbowałem ur 'First' i jego wyjątek generowania jako identyfikator klienta nie istnieje w klientem, ale jak powiedziałem, że nie jest konieczne – Hunt

+0

pytanie brzmi, co się stanie, gdy masz zwróconą wartość. –

+0

Próbowałem twój "Pierwszy" zbyt, ale ten sam problem. gdy 'ReadJson' zwraca dane zmienna odbierająca dane jest pusta zawsze spróbuj – Hunt

2
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; } 
} 
+0

czy chcesz powiedzieć raczej "IList " powinienem używać tylko "oferty"? – Hunt

+0

Nie mam na myśli przenieść twojego atrybutu JsonConverter do klasy notowań – Gurpreet

1

Wierzę, że ta metoda konwertera jest nieprawidłowy

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

objectType w tym przypadku byłoby typu IList<Quotation> nie JsonConverter<IList<Quotation>>. Wierzę, że powinno to brzmieć:

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

edytuj: Chociaż uważam, że jest to nieprawidłowe, nie wierzę już, że to jest podstawowa przyczyna problemu.Dokładnie odwzorowałem problem, a poprawka polegała na zmianie tej linii.

public IList<Quotation> quotationsList { get; } 

do

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

JsonConvert potrzebuje publicznego setter, aby móc przypisać wartości właściwości.

Zmieniłem również tę linię

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

do

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

to mówi DeserializeObject zadzwonić do której klasy spróbować deserializowania się.