I had an ASP.net app in which we serialized a string content using BinaryFormatter like this :
BinaryFormatter bf = new BinaryFormatter();
try
{
using (MemoryStream ms = new MemoryStream())
{
bf.Serialize(ms, Content);
var SerializedContent = ms.GetBuffer();
return SerializedContent;
}
// ...
But now that BinaryFormatter has become obsolete I am getting exception. I have been trying to use XMLSerializer but haven't been able to make it work. This is what I have been trying:
XmlSerializer xmlSerializer = new XmlSerializer(Content.GetType());
using (MemoryStream ms = new MemoryStream())
{
xmlSerializer.Serialize(ms, Content);
var SerializedContent = ms.GetBuffer();
return SerializedContent;
}
// ...
But I don't get the correct output. What am I doing wrong?
Related
I need to use this:
http://www.newtonsoft.com/json/help/html/SerializeToBson.htm
This is code to convert object to BSON format. The code which interests me is this:
System.IO.MemoryStream stream = new System.IO.MemoryStream();
using (Newtonsoft.Json.Bson.BsonWriter writer = new Newtonsoft.Json.Bson.BsonWriter(stream))
{
Newtonsoft.Json.JsonSerializer serializer = new Newtonsoft.Json.JsonSerializer();
serializer.Serialize(writer, message);
}
However, I want the result in a string. So do I really have to use a stream or a file to write stuff in, then read it to put it in the string?
There must be a better way to do this?
You can get the string from the stream using StreamReader.ReadToEnd():
string bsonText = "";
using(MemoryStream stream = new MemoryStream())
using(StreamReader reader = new StreamReader(stream))
using (BsonWriter writer = new Newtonsoft.Json.Bson.BsonWriter(stream))
{
JsonSerializer serializer = new JsonSerializer();
serializer.Serialize(writer, message);
stream.Position = 0;
bsonText = reader.ReadToEnd();
}
Or also, Encoding.UTF8.GetString():
using(MemoryStream stream = new MemoryStream())
using (BsonWriter writer = new Newtonsoft.Json.Bson.BsonWriter(stream))
{
JsonSerializer serializer = new JsonSerializer();
serializer.Serialize(writer, message);
bsonText = Encoding.UTF8.GetString(stream.ToArray());
}
BTW who knows what you're going to get from this, since BSON is a binary object representation, it's not like JSON!
When i deserialize without GZip, it's done. But in deserializing with GZip i have deserialization error.
Serializing:
using (MemoryStream ms = new MemoryStream())
{
using (var compressionStream = new GZipStream(ms, CompressionMode.Compress))
{
serializator.Serialize(compressionStream, obj);
}
byte[] result = ms.ToArray();
return result;
}
Deserializing:
using (MemoryStream ms = new MemoryStream(_objBytes))
{
using (GZipStream decompressionStream = new GZipStream(ms, CompressionMode.Decompress))
{
return serializator.Deserialize(decompressionStream, null, objType, _objBytes.Length);
}
}
As stated in comments the number of bytes is wrong. Why are you ever specifying it? You can use overload without length parameter:
RuntimeTypeModel.Default.Deserialize(decompressionStream, null, objType);
I am looking for a way to serialize Avro to a byte array in Avro C# library. There is a link to do for Avro Java library as described in following link from Avro documentation:
https://cwiki.apache.org/confluence/display/AVRO/FAQ#FAQ-Serializingtoabytearray
Code copied from above link:
ByteArrayOutputStream out = new ByteArrayOutputStream();
BinaryEncoder encoder = EncoderFactory.get().binaryEncoder(out, null);
DatumWriter<User> writer = new SpecificDatumWriter<User>(User.getClassSchema());
writer.write(user, encoder);
encoder.flush();
out.close();
byte[] serializedBytes = out.toByteArray();
But I have not found a way to do in Avro c# library. I am basically looking for c# equivalent of above code.
You can use these methods to convert to and from an object to a byte array or vice-versa. Code extracted from https://stackoverflow.com/a/18205093/6138713
// Convert an object to a byte array
private byte[] ObjectToByteArray(Object obj)
{
if(obj == null)
return null;
BinaryFormatter bf = new BinaryFormatter();
MemoryStream ms = new MemoryStream();
bf.Serialize(ms, obj);
return ms.ToArray();
}
// Convert a byte array to an Object
private Object ByteArrayToObject(byte[] arrBytes)
{
MemoryStream memStream = new MemoryStream();
BinaryFormatter binForm = new BinaryFormatter();
memStream.Write(arrBytes, 0, arrBytes.Length);
memStream.Seek(0, SeekOrigin.Begin);
Object obj = (Object) binForm.Deserialize(memStream);
return obj;
}
Maybe something as follows, I used the following code to write to a Kineses Stream
public async Task RecordAsync(ISpecificRecord record, string partitionKey)
{
using (var ms = new MemoryStream())
{
var encoder = new BinaryEncoder(ms);
var writer = new SpecificDefaultWriter(record.Schema);
writer.Write(record, encoder);
// AWS Kineses
var putRecordRequest = new PutRecordRequest
{
StreamName = _streamName,
Data = ms,
PartitionKey = partitionKey
};
await _kinesis.PutRecordAsync(putRecordRequest);
}
}
or
public byte[] Serialize(ISpecificRecord record)
{
using (var ms = new MemoryStream())
{
var encoder = new BinaryEncoder(ms);
var writer = new SpecificDefaultWriter(record.Schema);
writer.Write(record, encoder);
return ms.ToArray();
}
}
BinaryFormatter formatter = new BinaryFormatter();
using (MemoryStream m = new MemoryStream())
{
formatter.Serialize(m, list);
StreamReader sr = new StreamReader(m);
HiddenField1.Value = sr.ReadToEnd();
}
i'm getting a blank value for HiddenField1.Value. Not sure what I'm doing is even possible? list is definitely populated (is a List<T>)
Depending on what you want to achieve... One option is to show content of the binary stream as Base64 string:
var memoryStream = new MemoryStream();
using(memoryStream)
{
formatter.Serialize(memoryStream, list);
}
HiddenField1.Value = Convert.ToBase64String(memoryStream.ToArray());
Change it to:
BinaryFormatter formatter = new BinaryFormatter();
using (MemoryStream m = new MemoryStream())
{
formatter.Serialize(m, list);
m.Position = 0;
StreamReader sr = new StreamReader(m);
HiddenField1.Value = sr.ReadToEnd();
}
You need to reset the position of the stream back to the beginning before reading it. Also, you shouldn't use StreamReader to convert a binary stream like this to text, because it will break in unexpected ways. If you want the results in a text-like format, use Convert.ToBase64String as in #Alexei's answer.
I am trying to deserialize a stream but I always get this error "End of Stream encountered before parsing was completed"?
Here is the code:
//Some code here
BinaryFormatter b = new BinaryFormatter();
return (myObject)b.Deserialize(s);//s---> is a Stream object that has been fill up with data some line over here
Any one have ideas?
Try to set the position to 0 of your stream and do not use your object but the object type.
BinaryFormatter b = new BinaryFormatter();
s.Position = 0;
return (YourObjectType)b.Deserialize(s);
Make sure the serialization completed, and that the serialization type matches the de-serialization type (i.e., make sure you're serializing with a BinaryFormatter if you're de-serializing with one). Also, make sure that the stream you serialized to really finished serializing, with a Stream.Flush() or something to that effect.
I had the same exception thrown, until I added the [Serializable] tag to the class I was Serializing :)
Then it all worked perfectly.
In my case I used:
stream.Seek(0, SeekOrigin.Begin);
after i serialized the stream, and before i deserialized the stream works charm. hope this helps!
I have spent 5 hourse and have got end of stream error and lost data (Not obvious feature in GzipStream: you should use underlying stream only after flush GzipStream).
Full example of working code:
using System;
using System.IO;
using System.IO.Compression;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
namespace ConsoleApp3
{
class Program
{
static void Main(string[] args)
{
string large = LargeJsonContent.GetBigObject();
string base64;
using (var readStream = new MemoryStream())
using (var writeStream = new MemoryStream())
{
using (GZipStream compressor = new GZipStream(writeStream, CompressionMode.Compress, true)) //pay attention to leaveOpen = true
{
var formatter = new BinaryFormatter();
formatter.Serialize(readStream, large);
Console.WriteLine($"After binary serialization of JsonString: {readStream.Length} bytes");
readStream.Position = 0;
readStream.CopyTo(compressor);
}
Console.WriteLine($"Compressed stream size: {writeStream.Length} bytes");
writeStream.Position = 0;
byte[] writeBytes = writeStream.ToArray();
base64 = Convert.ToBase64String(writeBytes);
}
////
using (var stream = new MemoryStream())
{
var formatter = new BinaryFormatter();
formatter.Serialize(stream, base64);
Console.WriteLine($"Size of base64: {stream.Length} bytes");
}
Console.WriteLine("---------------------");
////
string large2;
var bytes = Convert.FromBase64String(base64);
using (var readStream = new MemoryStream())
{
readStream.Write(bytes, 0, bytes.Length);
readStream.Position = 0;
Console.WriteLine($"Compressed stream size: {readStream.Length} bytes");
using (var writeStream = new MemoryStream())
{
using (GZipStream decompressor = new GZipStream(readStream, CompressionMode.Decompress, true)) //pay attention to leaveOpen = true
{
decompressor.CopyTo(writeStream);
writeStream.Position = 0;
}
var formatter = new BinaryFormatter();
large2 = (string)formatter.Deserialize(writeStream);
}
}
Console.WriteLine(large == large2);
Console.WriteLine($"large:{large.Length} | large2:{large2.Length}");
}
}
}
Check in your sender code if you are not doing the following
NetworkStream strm = client.GetStream(); // the stream
formatter.Serialize(strm, status); // the serialization process
strm.Close();// Remove this code, this was the culprit in my case
the class which you created must has [Serializable].