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!
Related
I already searched a lot and unable to find a solution and unable to determine the correct approach
I am serializing an object to xml string and deserializing it back to an object using c#. XML string after serialization adds a leading ?. When I dezerialize it back to the object I am getting an error There is an error in XML document (1, 1)
?<?xml version="1.0" encoding="utf-16"?>
Serialization code:
string xmlString = null;
MemoryStream memoryStream = new MemoryStream();
XmlSerializer xs = new XmlSerializer(typeof(T));
XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add("abc", "http://example.com/abc/");
XmlTextWriter xmlTextWriter = new XmlTextWriter(memoryStream,Encoding.Unicode);
xs.Serialize(xmlTextWriter, obj, ns);
memoryStream = (MemoryStream)xmlTextWriter.BaseStream;
xmlString = ConvertByteArrayToString(memoryStream.ToArray());
ConvertByteArrayToString:
UnicodeEncoding encoding = new UnicodeEncoding();
string constructedString = encoding.GetString(characters);
Deserialization Code:
XmlSerializer ser = new XmlSerializer(typeof(T));
StringReader stringReader = new StringReader(xml);
XmlTextReader xmlReader = new XmlTextReader(stringReader);
object obj = ser.Deserialize(xmlReader);
xmlReader.Close();
stringReader.Close();
return (T)obj;
I would like to know what I am doing wrong with encoding and I need a solution that works for most cases. Thanks
Use following function for serialization and Deserialization
public static string Serialize<T>(T dataToSerialize)
{
try
{
var stringwriter = new System.IO.StringWriter();
var serializer = new XmlSerializer(typeof(T));
serializer.Serialize(stringwriter, dataToSerialize);
return stringwriter.ToString();
}
catch
{
throw;
}
}
public static T Deserialize<T>(string xmlText)
{
try
{
var stringReader = new System.IO.StringReader(xmlText);
var serializer = new XmlSerializer(typeof(T));
return (T)serializer.Deserialize(stringReader);
}
catch
{
throw;
}
}
Your serialized XML contains a Unicode byte-order mark in the beginning, and this is where the deserializer fails.
To remove the BOM you need to create a different version of encoding suppressing BOM instead of using default Encoding.Unicode:
new XmlTextWriter(memoryStream, new UnicodeEncoding(false, false))
Here the second false prevents BOM being prepended to the string.
I'm trying to serialize very large object directly to a zip stream. I manage to do this by serializing to a file stream in an intermediate step, loading it back and then compressing it.
I've also tried compressing directly to a memory stream and it works. But when i use a GZipStream I'm always left with an "unfinished" object, the data is there it's correctly formatted up to the point where it ends unexpectedly.
It's not for lack of flushing buffers since I've already tried flushing everything.
Simplified sample code:
internal static byte[] SerializeAndCompress(object objectToSerialize)
{
using(var memStream = new MemoryStream())
using (var zipStream = new GZipStream(memStream, CompressionMode.Compress, true))
using (var streamWriter = new StreamWriter(zipStream))
using (var jsonWriter = new JsonTextWriter(streamWriter))
{
var jsonSerializer = new JsonSerializer { ContractResolver = new CamelCasePropertyNamesContractResolver(), Formatting = Newtonsoft.Json.Formatting.None };
jsonSerializer.Serialize(jsonWriter, objectToSerialize);
jsonWriter.Flush();
return memStream.ToArray();
}
}
Thanks.
Rather than flushing the writer, I suggest you close it completely. That way the GZipStream knows there's no more data to write and can add any appropriate checksums or whatever it needs to do.
You could either call Close explicitly, or put it between the closing parts of using statements:
using(var memStream = new MemoryStream())
{
using (var zipStream = new GZipStream(memStream, CompressionMode.Compress, true))
using (var streamWriter = new StreamWriter(zipStream))
using (var jsonWriter = new JsonTextWriter(streamWriter))
{
var jsonSerializer = new JsonSerializer { ContractResolver = new CamelCasePropertyNamesContractResolver(), Formatting = Newtonsoft.Json.Formatting.None };
jsonSerializer.Serialize(jsonWriter, objectToSerialize);
}
return memStream.ToArray();
}
Note that by the time you call ToArray, the MemoryStream will already be closed, but that's okay - the data will still be there.
This must be very simple but I can't find it by searching.
I have the following code to serialize an object to a file and back. But now I want to serialize to a byte[] and back.
XmlSerializer serializer = new XmlSerializer(typeof(Class1));
using (TextWriter textWriter = new StreamWriter(path))
serializer.Serialize(textWriter, class1);
using (TextReader textReader = new StreamReader(path))
class1b = (Class1)serializer.Deserialize(textReader);
I tried using a MemoryStream:
byte[] buffer = new byte[1000];
using (TextWriter textWriter = new MemoryStream(buffer))
...
but I get an error. So how should I do it?
You should send the stream to the StreamWriter instead of trying to assign the Stream to a TextWriter.
using (var stream = new MemoryStream(buffer))
{
using (TextWriter textWriter = new StreamWriter(stream))
{ ... }
}
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.
My method returns Dictionary<TZerokey, Dictionary<TFirstKey, Dictionary<TSecondKey,Dictionary<TThirdKey,TValue>>>> and i would to serialise/deserialise this object as XML using DataContractSerialiser.
Below are my methods:
public static void SerializeDictionaryToXml<T>(this T obj, string fileName)
{
DataContractSerializer ser = new DataContractSerializer(typeof(T));
// System.Xml.Serialization.XmlSerializer ser = new System.Xml.Serialization.XmlSerializer(typeof(T));
FileStream fileStream = new FileStream(fileName, FileMode.Create);
ser.WriteObject(fileStream, obj);
fileStream.Close();
}
public static T DeserializeDictionaryFromXml<T>(string xml)
{
FileStream fs = new FileStream(xml,
FileMode.Open);
XmlDictionaryReader reader = XmlDictionaryReader.CreateTextReader(fs, new XmlDictionaryReaderQuotas());
DataContractSerializer ser = new DataContractSerializer(typeof(T));
// Deserialize the data and read it from the instance.
T deserializedObject = (T)ser.ReadObject(reader, true);
reader.Close();
fs.Close();
return deserializedObject;
}
The code runs fine except that I do not get the expected output. Can someone see what I'm doing wrong?