How to Convert an Object to a Byte Array in C#

Convert any object to a byte[]

Use the BinaryFormatter:

byte[] ObjectToByteArray(object obj)
{
if(obj == null)
return null;
BinaryFormatter bf = new BinaryFormatter();
using (MemoryStream ms = new MemoryStream())
{
bf.Serialize(ms, obj);
return ms.ToArray();
}
}

Note that obj and any properties/fields within obj (and so-on for all of their properties/fields) will all need to be tagged with the Serializable attribute to successfully be serialized with this.

C# object to byte[]

You may try this:

TypeConverter obj = TypeDescriptor.GetConverter(objectMessage.GetType());
byte[] bt = (byte[])obj.ConvertTo(objectMessage, typeof(byte[]));

Convert class object to bytes and create object from bytes

Ok this maybe what your looking for

The assumptions gleaned from your comments and updates are as follows

  • You want a generic way to serialize your classes (messages)
  • You want to be able to use this over the wire (sockets, not wcf)
  • It conforms to a socket regime
  • You want some basic protection against corruption
  • you want it easy to use

Note : there maybe many areas here which can be improved, however this is just to give you some ideas

If your using something like webservices this entire answer is null and void, this is really only a adhock method of serialization suitable for sockets

Overview

The Package class has some methods for the following

  • Able to serialize objects to bytes
  • Able to deserialize bytes to objects
  • Can create packages with header information
  • Header contains your message type (Option)
  • The length of the entire package
  • Some basic check summing and markers, in case of corruptions you can validate a package

So given the following

Message Enum

// Some predefined messages
public enum MessageType : byte
{
MyClass,
MyOtherClass,
Message3,
Message4,

}

Some class you want to send over the wire

// a serilaizable class
// Make this as you like
[Serializable]
public class MyClass
{

public byte[] SomeArbitaryBytes { get; set; }
public string SomeArbitaryString { get; set; }
public int SomeArbitaryInt { get; set; }
public double SomeArbitaryDouble { get; set; }

public MyClass()
{

SomeArbitaryString = "hello";
SomeArbitaryInt = 7;
SomeArbitaryDouble = 98.1;
SomeArbitaryBytes = new byte[10];
for (var i = 0; i < SomeArbitaryBytes.Length; i++)
{
SomeArbitaryBytes[i] = (byte)i;
}
}
}

Package Class

public static class Package
{
// Method for basic checksum
private static byte GetBasicChecksum(this byte[] data)
{
byte sum = 0;
unchecked // Let overflow occur without exceptions
{
foreach (byte b in data)
{
sum += b;
}
}
return sum;
}

// Serialize to bytes (BinaryFormatter)
public static byte[] SerializeToBytes<T>(this T source)
{
using (var stream = new MemoryStream())
{
var formatter = new BinaryFormatter();
formatter.Serialize(stream, source);
return stream.ToArray();
}
}

// Deerialize from bytes (BinaryFormatter)
public static T DeserializeFromBytes<T>(this byte[] source)
{
using (var stream = new MemoryStream(source))
{
var formatter = new BinaryFormatter();
stream.Seek(0, SeekOrigin.Begin);
return (T)formatter.Deserialize(stream);
}
}

// Check if we have enough data
// will throw if it detects a corruption (basic)
// return false if there isnt enough data to determine
// return true and length of the package if sucessfull
public static bool HasValidPackage(this Stream stream, out Int32 messageSize)
{
messageSize = -1;

if (stream.Length - stream.Position < sizeof(byte) * 2 + sizeof(Int32))
return false;

var stx = stream.ReadByte();

if (stx != 2)
throw new InvalidDataException("Invalid Package : STX Failed");

var packageLength = new byte[sizeof(Int32)];
stream.Read(packageLength, 0, sizeof(Int32));
messageSize = BitConverter.ToInt32(packageLength, 0) - sizeof(byte) * 3;
var checkSum = stream.ReadByte();

if (checkSum != packageLength.GetBasicChecksum())
throw new InvalidDataException("Invalid Package : CheckSum Failed");

return stream.Length >= messageSize;

}

// Pack the message
public static byte[] PackMessage<T>(this T source, MessageType messageType)
{
var buffer = source.SerializeToBytes();
var packageLength = BitConverter.GetBytes(buffer.Length + sizeof(byte) * 3);
using (var stream = new MemoryStream())
{
stream.WriteByte(2);
stream.Write(packageLength, 0, sizeof(Int32));
stream.WriteByte(packageLength.GetBasicChecksum());
stream.WriteByte((byte)messageType);
stream.Write(buffer, 0, buffer.Length);
stream.WriteByte(3);
return stream.ToArray();
}
}

// Unpack the message
public static MessageType UnPackMessage(this Stream stream, Int32 messageSize, out byte[] buffer)
{

var messageType = (MessageType)stream.ReadByte();
buffer = new byte[messageSize];
stream.Read(buffer, 0, buffer.Length);

var etx = stream.ReadByte();

if (etx != 3)
throw new InvalidDataException("Invalid Package : ETX Failed");

return messageType;
}

}

Client Side Code

// create your class 
var myClass = new MyClass();

// Create a package out of it
var bytes = myClass.PackMessage(MessageType.MyClass);

Server Side Code

// this is server side
using (var stream = new MemoryStream(bytes))
{
Int32 messageSize;

// if we have a valid package do stuff
// this loops until there isnt enough data for a package or empty
while (stream.HasValidPackage(out messageSize))
{

byte[] buffer;

switch (stream.UnPackMessage(messageSize, out buffer))
{
case MessageType.MyClass:
var myClassCopy = buffer.DeserializeFromBytes<MyClass>();
// do stuff with your class
break;
case MessageType.MyOtherClass:
break;
case MessageType.Message3:
break;
case MessageType.Message4:
break;
default:
throw new ArgumentOutOfRangeException();
}

}

// do something with the remaining bytes here, if any, i.e partial package

}

Cast object array to byte array

You may use binary serialization and deserialization for Serializable types.

using System.Runtime.Serialization.Formatters.Binary;

BinaryFormatter binary = BinaryFormatter();
using (FileStream fs = File.Create(file))
{
bs.Serialize(fs, objectArray);
}

Edit: If all these elements of an array are simple types then use BitConverter.

object[] arr = { 10.20, 1, 1.2f, 1.4, 10L, 12 };
using (MemoryStream ms = new MemoryStream())
{
foreach (dynamic t in arr)
{
byte[] bytes = BitConverter.GetBytes(t);
ms.Write(bytes, 0, bytes.Length);
}
}

convert an object to a byte array with defined method in other class in C#

Here is an example using System.Runtime.Serialization.Formatters.Binary.BinaryFormatter and the [Serializable()] attribute for the structure.

[Serializable()]
public struct Convertor
{
public string License { get; set; }
public int Software { get; set; }
public int StartDate { get; set; }
public int EndDate { get; set; }
public byte Count { get; set; }
public int[] ActionCode { get; set; }

public byte[] ConvertToArray()
{
var bf = new BinaryFormatter();
using (var mem = new MemoryStream())
{
bf.Serialize(mem, this);
return mem.ToArray();
}
}

public static Convertor ConvertFromArray(byte[] buffer)
{
var bf = new BinaryFormatter();
using (var mem = new MemoryStream(buffer))
{
return (Convertor)bf.Deserialize(mem);
}
}

/// <summary>
/// Checks for equality among <see cref="Convertor"/> classes
/// </summary>
/// <param name="other">The other <see cref="Convertor"/> to compare it to</param>
/// <returns>True if equal</returns>
public bool Equals(Convertor other)
{
return License == other.License
&& Software == other.Software
&& StartDate == other.StartDate
&& EndDate == other.EndDate
&& Count == other.Count
&& ActionCode.SequenceEqual(other.ActionCode);
}

}
class Program
{
static void Main(string[] args)
{
// Create a new object and add some data to it
var a = new Convertor()
{
License = "ABC001",
Software = 1,
StartDate = 2018,
EndDate = 2019,
Count = 16,
ActionCode = new[] { 67, 79, 68, 69, 49, 50, 51 }
};

// Serialize the object into a byte array
var buffer = a.ConvertToArray();

// Deserialize a new object from the byte array
var b = Convertor.ConvertFromArray(buffer);

// Check for equality
var ok = a.Equals(b); // ok = true
}
}

How to convert object in byte[] c#

I managed to do, what I needed to adjust to not use Connetion, but create and discard in each block that was to be used



Related Topics



Leave a reply



Submit