Konuyu Oyla:
  • Derecelendirme: 4/5 - 1 oy
  • 1
  • 2
  • 3
  • 4
  • 5
REST.Json, TJSon.JsonToObject sorunsalı
#1
Benzer bir konu forumda görüm ama oradaki son mesaj neredeyse 1 sene önce atılmış olduğundan hortlatmayayım diye, ayrı bir başlık olarak yazmak istedim.

REST.JSon ile, Delphi uygulamasında bir nesnemden ürettiğim JSon metnini .net ile yazdığım başka bir socket uygulamama gönderiyorum. Orada Deserialize edip, işlemi yapıp, aynı nesne tipiyle geriye yanıtı Serialize edip JSon olarak gönderiyorum. Ancak, Delphi uygulamamda, .net socket uygulamadan gelen bu yanıtı TJSon.JsonToObject ile nesneme çevirmek istediğimde boş olarak nesneleştiriyor.

Forumda ve nette bulabildiğim mevcut örnekleri inceledim ve olası şekilleri denedim. 
JSon metninde de sorun olmadığını düşünüyorum zira .net ile aynı denemeyi yaptığımda yapabiliyor. Nesnemin yapısında TArray' ler mevcut. bununla ilgili olabilir mi ? Veya nesnenin alt nesnelerindekilerin null dönmesi .nette sorun çıkarmazken Delphi de soruna mı yol açıyor ?

Serialize ettiği bir nesneyi neden tekrar nesneleştiremediğini bulamadım, önerisi olan var mı ?


Kod yapısı kabaca şöyle :

// Deklarasyon

Type TAltNesne = Class

   Private

       _iValAlt            : Integer;
       _sValAlt            : String;

   Public

       Property iValAlt     : Integer read _iValAlt write _iValAlt;
       Property sValAlt     : Integer read _sValAlt write _sValAlt;

End;

Type TMembers = Class

   Private

       _iVal            : Integer;
       _sVal            : String;
       _AltNesne        : TArray<TAltNesne>;

   Public

       Property iVal     : Integer read _iVal write _iVal;
       Property sVal     : Integer read _sVal write _sVal;
       Property AltNesne : TArray<TAltNesne> read _AltNesne write _AltNesne;

End;

Type TNesne = Class

   Private

       _responseResult   : Boolean;
       _responseMessage  : String;
       _responseMembers  : TMembers;

   Public

       Property responseResult   : Boolean read _responseResult  write _responseResult;
       Property responseMessage  : String  read _responseMessage write _responseMessage;
       Property responseMembers  : TMembers read _responseMembers write _responseMembers;

End;


// Çağrılan kısım :

var tempResponse : TNesne; 
tempResponse := TJSon.JsonToObject<TNesne>(sJSonDonen);
Cevapla
#2
Merhaba,
Delphi 10.2.3 ve Delphi 10.3.1 ile yaptığım projelerde bu metodu (JsonToObject) uzun süredir (iki farklı projemde) kullanıyorum.
Şu ana kadar herhangi bir sorun yaşamadım. 
TNesne objeniz, JSON verisi ile gelen tüm propery'leri içermeli ve bu sınıf üye adları ile JSON verisi içerisindeki alan adları bire bir aynı olmalıdır. Aksi durumda çözümlenemiyor.
While true do; Hayat döngüsü, kısır değildir! Yapılan bir yanlış, o döngünün dışına çıkmanızı sağlayacaktır.
WWW
Cevapla
#3
Fesih bey ilginize teşekkürler. Sorunun kaynağını biraz önce buldum.
Enteresan ve bence anlamsız ama, Private değişkenlerin isimlerini 'F' harfiyle başlayacak şekilde değiştirince sorun düzeliyor. Örnek : _sVal yerine FVal.
Sorunu çözmek için, request için oluşturulan ve .net tarafında sorunsuz kabul edilen JSon stringini, .net' socket uygulamasına göndermeden önce tekrar kendi nesne tipine çevirip denedim.
Daha o aşamada bile kendi ürettiğini çeviremiyordu. Belki alt nesnelerdendir deyip, onları da deklerasyonundan kaldırdım, sadece tek bir integer property bıraktım. Yine çeviremedi. En son bir yerde bulduğum örnekteki gibi 'F' ile Private değişken isimlerini değiştirdiğimde çalıştı (Alt nesneleri dahil) ...

Neden böyle birşey var anlam veremedim ama en azından sorunun bu şekilde çözüldüğünü görmek biraz rahatlattı, baya uğraştırdı beni zira ...
Cevapla
#4
(13-05-2019, Saat: 12:57)Gürcan Adlı Kullanıcıdan Alıntı: Fesih bey ilginize teşekkürler. Sorunun kaynağını biraz önce buldum.
Enteresan ve bence anlamsız ama, Private değişkenlerin isimlerini 'F' harfiyle başlayacak şekilde değiştirince sorun düzeliyor. Örnek : _sVal yerine FVal.
Sorunu çözmek için, request için oluşturulan ve .net tarafında sorunsuz kabul edilen JSon stringini,  .net' socket uygulamasına göndermeden önce tekrar kendi nesne tipine çevirip denedim.
Daha o aşamada bile kendi ürettiğini çeviremiyordu. Belki alt nesnelerdendir deyip, onları da deklerasyonundan kaldırdım, sadece tek bir integer property bıraktım. Yine çeviremedi. En son bir yerde bulduğum örnekteki gibi 'F' ile Private değişken isimlerini değiştirdiğimde çalıştı (Alt nesneleri dahil) ...

Neden böyle birşey var anlam veremedim ama en azından sorunun bu şekilde çözüldüğünü görmek biraz rahatlattı, baya uğraştırdı beni zira ...

Ben hep private değişkenleri F ile başladığım için sorun yaşamamış olabilirim. Smile
Kullandığım örnek obje;
type
  TTokenSes = class
 private
   FAccess_token: String;
   FExpires_in: Extended;
   FToken_type: String;
 public
   property access_token: String read FAccess_token write FAccess_token;
   property expires_in: Extended read FExpires_in write FExpires_in;
   property token_type: String read FToken_type write FToken_type;
   /// <summary>
   /// API Servisinden gelen JSON veriyi çözümler ve TTokenSes sınıfına dönüştürür.
   /// </summary>
   class function FromJsonString(AJsonString: string): TTokenSes;
 end;
While true do; Hayat döngüsü, kısır değildir! Yapılan bir yanlış, o döngünün dışına çıkmanızı sağlayacaktır.
WWW
Cevapla
#5
Artık ömrüm boyunca tüm private değişkenleri F ile başlatırım herhalde Smile
Cevapla
#6
F yerine başka bir harf deneyebilir misiniz, mesela X gibi. Sorun değişken isimlerinin "F" ile başlamaması değil, "_" ile başlatmanız olabilir diye düşünüyorum. Dediğimi test etme şansınız varsa konuyu daha sonradan okuyacaklar için daha net bir cevap olmuş olur.
Cevapla
#7
G ile başlatıp denedim, yine çalışmadı.
Sadece F ile kabul ediyor. Garip ama gerçek Smile
Cevapla
#8
Bu konuya bir göz atabilir misiniz.
Alıntı:JSON serialization in Delphi is based on fields, not properties. But most of Delphi classes have friendly properties and F-prefixed fields. At same time seems Emb is trying to avoid of F-prefixed names in generated JSON. They cut off first "F" from name when serialize fields and add it back (to find correct field) when read from JSON. Seems the only (safe) way to use JSON serialization in Delphi is to keep all field names with prefix "F" (for the fields that you want to serialize):
WWW
Cevapla
#9
(13-05-2019, Saat: 13:40)ismailkocacan Adlı Kullanıcıdan Alıntı: Bu konuya bir göz atabilir misiniz.
Alıntı:JSON serialization in Delphi is based on fields, not properties. But most of Delphi classes have friendly properties and F-prefixed fields. At same time seems Emb is trying to avoid of F-prefixed names in generated JSON. They cut off first "F" from name when serialize fields and add it back (to find correct field) when read from JSON. Seems the only (safe) way to use JSON serialization in Delphi is to keep all field names with prefix "F" (for the fields that you want to serialize):


Teşekkürler İsmail bey, inceleyeceğim.
Cevapla
#10
Siz sorununuzu çözmüşsünüz ama ileride konuyu okuyanlara yararı olabilir:
Ben bu tarz işlerde (farklı dillerde yazılmış 2 projede sınıf paylaşımı vs.) Google Protocol Buffers kullanıyorum. Tavsiye ederim.
There's no place like 127.0.0.1
WWW
Cevapla


Konu ile Alakalı Benzer Konular
Konular Yazar Yorumlar Okunma Son Yorum
  Delphi 7 json veri işlemleri onurakman 8 338 17-04-2019, Saat: 11:22
Son Yorum: OBK
  Json Free Etmek yhackup 3 148 10-04-2019, Saat: 16:51
Son Yorum: esistem
  [Çözüldü] JSon String içindeki son altı bilgi CesuR 7 322 23-03-2019, Saat: 18:15
Son Yorum: Fesih ARSLAN
Thumbs Up tarih sorunsalı ! forumcuali 1 190 06-03-2019, Saat: 08:29
Son Yorum: Tuğrul HELVACI
  Thread.FFatalException (TJSON) yhackup 8 272 04-03-2019, Saat: 11:24
Son Yorum: edo



Konuyu Okuyanlar: 1 Ziyaretçi