xsharp.eu • Generics are really cool!
Page 1 of 1

Generics are really cool!

Posted: Tue May 21, 2019 8:00 pm
by wriedmann
Hi,

today I had to serialize and to unserialize JSON data.
The code Microsoft showed in his samples is here: https://docs.microsoft.com/en-us/dotnet ... -json-data

Using a static class with static methods simplified things very much:

Code: Select all

using System.Runtime.Serialization
using System.Runtime.Serialization.Json
using System.IO
static class JsonHelper

static method Serialize<T>( oObject as T ) as string
  local oSerializer as DataContractJsonSerializer
  local oStream as MemoryStream
  local oReader as StreamReader
  local cResult as string

  oSerializer := DataContractJsonSerializer{ typeof( T ) }
  oStream := MemoryStream{}
  oSerializer:WriteObject( oStream, oObject )
  oStream:Position := 0
  oReader := StreamReader{ oStream }
  cResult := oReader:ReadToEnd()
  oReader:Close()
  oReader:Dispose()
  oStream:Close()
  oStream:Dispose()

  return cResult

static method Deserialize<T>( cJsonString as string ) as T
  local oResult as T
  local oStream as MemoryStream
  local oWriter as StreamWriter
  local oSerializer as DataContractJsonSerializer

  oStream := MemoryStream{}
  oWriter := StreamWriter{ oStream }
  oWriter:Write( cJsonString )
  oWriter:Flush()
  oStream:Position := 0
  oSerializer := DataContractJsonSerializer{ typeof( T ) }
  oResult  := ( T ) oSerializer:ReadObject( oStream )
  oWriter:Close()
  oWriter:Dispose()
  oStream:Close()
  oStream:Dispose()

  return oResult

end class
Using this code is really simple:

Code: Select all

oLoginData := LoginData{ "user", "pass" }
cJsonString := JsonHelper.Serialize<LoginData>( oLoginData )
System.Console.WriteLine( cJsonString )
oLoginData := JsonHelper.Deserialize<LoginData>( cJsonString )
System.Console.WriteLine( String.Format( "Login:{0}, Password:{1}", oLoginData:username, oLoginData:password ) )
This code may not be the cleanest or best or error free solution, but it works for me.

Wolfgang
P.S. to make this work, you need the System.Runtime.Serialization and System.XML assemblies in the references.

And here is a small XIDE export file with sample code:
JsonTester.zip
(1.67 KiB) Downloaded 108 times

Generics are really cool!

Posted: Tue May 21, 2019 9:33 pm
by NickFriend
Nice Wolfgang, I agree, generics are really great.

On this general subject I have a static class that will compress/decompress strings, byte arrays and streams, and will also serialize and compress any object (and the reverse of course), It's in C#, but if you're interested I could send it to you and you could translate it to X# for everyone.

Nick

Generics are really cool!

Posted: Wed May 22, 2019 4:03 am
by wriedmann
Hi Nick,
On this general subject I have a static class that will compress/decompress strings, byte arrays and streams, and will also serialize and compress any object (and the reverse of course), It's in C#, but if you're interested I could send it to you and you could translate it to X# for everyone.
If you are willing to share it, I will try to translate it.
I already have a extension methods to the string class that compresses and uncompresses:

Code: Select all

static class StringExtensions

static method Compress( self cString as string ) as string
  local aBuffer as byte[]
  local aCompressed as byte[]
  local cReturn as string
  local oMemory as MemoryStream
  local oGZip as GZipStream
  local nUncompressedLen as int32

  if String.IsNullOrEmpty( cString )
    cReturn := ""
  else
    aBuffer := Encoding.UTF8:GetBytes( cString )
    nUncompressedLen := aBuffer:Length
    oMemory := MemoryStream{}
    oGZip := GZipStream{ oMemory, CompressionMode.Compress, true }
    oGZip:Write( aBuffer, 0, aBuffer:Length )
    oGZip:Close()
    oGZip := null
    oMemory:Position := 0
    aCompressed := byte[]{ oMemory:Length }
    oMemory:Read( aCompressed, 0, aCompressed:Length )
    oMemory:Close()
    aBuffer := byte[]{ aCompressed:Length + 4 }
    Buffer.BlockCopy( aCompressed, 0, aBuffer, 4, aCompressed:Length )
    Buffer.BlockCopy( BitConverter.GetBytes( nUncompressedLen ), 0, aBuffer, 0, 4 )
    cReturn := Convert.ToBase64String( aBuffer )
    aBuffer := null
    aCompressed := null
endif

return cReturn

static method Uncompress( self cString as string ) as string
  local cReturn as string
  local aBuffer as byte[]
  local aCompressed as byte[]
  local oMemory as MemoryStream
  local oGZip as GZipStream
  local nLength as int32

  if String.IsNullOrEmpty( cString )
    cReturn := ""
  else
    aCompressed := Convert.FromBase64String( cString )
    oMemory := MemoryStream{}
    nLength := BitConverter.ToInt32( aCompressed, 0 )
    oMemory:Write( aCompressed, 4, aCompressed:Length - 4 )
    aBuffer := byte[]{ nLength }
    oMemory:Position := 0
    oGZip := GZipStream{ oMemory, CompressionMode.Decompress, true }
    oGZip:Read( aBuffer, 0, aBuffer:Length )
    oGZip:Close()
    oMemory:Close()
    cReturn := Encoding.UTF8:GetString( aBuffer )
    aCompressed := null
    aBuffer := null
  endif

  return cReturn
Wolfgang

Generics are really cool!

Posted: Wed May 22, 2019 5:33 am
by SHirsch
Hi Wolfgang,

for handling Json I recommand using Newtonsoft.JsonNewtonsoft.
This is not just for serialize/deserialize. Query data is possible in many ways. This is a very powerful library.
Here two short samples:
deserialize:

Code: Select all

VAR br := (BookingRequest)JsonConvert.DeserializeObject<BookingRequest>( jStrBR )
query special item:

Code: Select all

VAR jBR := JObject.Parse( jStrBR )                       
VAR custId:= jBR:SelectToken("BookingRequest.CustomerId"):ToString()
Stefan

Generics are really cool!

Posted: Wed May 22, 2019 5:59 am
by wriedmann
Hi Stefan,

I have shortly tried to understand this library, but had not the expected results. And since I was in a hurry I have used the Microsoft Json library that is available since .NET 4.5.

Maybe I have to look again to the Newtonsoft library - or/and to enhance my own VO based version.

Wolfgang