Generics are really cool!

Public forum to share code snippets, screen shorts, experiences, etc.
Post Reply
User avatar
wriedmann
Posts: 3644
Joined: Mon Nov 02, 2015 5:07 pm
Location: Italy

Generics are really cool!

Post 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 68 times
Wolfgang Riedmann
Meran, South Tyrol, Italy
wolfgang@riedmann.it
https://www.riedmann.it - https://docs.xsharp.it
NickFriend
Posts: 248
Joined: Fri Oct 14, 2016 7:09 am

Generics are really cool!

Post 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
User avatar
wriedmann
Posts: 3644
Joined: Mon Nov 02, 2015 5:07 pm
Location: Italy

Generics are really cool!

Post 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
Wolfgang Riedmann
Meran, South Tyrol, Italy
wolfgang@riedmann.it
https://www.riedmann.it - https://docs.xsharp.it
User avatar
SHirsch
Posts: 281
Joined: Tue Jan 30, 2018 8:23 am

Generics are really cool!

Post 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
User avatar
wriedmann
Posts: 3644
Joined: Mon Nov 02, 2015 5:07 pm
Location: Italy

Generics are really cool!

Post 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
Wolfgang Riedmann
Meran, South Tyrol, Italy
wolfgang@riedmann.it
https://www.riedmann.it - https://docs.xsharp.it
Post Reply