Converting code to use JSON.net instead of System.Runtime.Serialization.DataContractSerializer - c#

How do I do the equivalent in JSON.net?
public SerializedResults SerializeResults(Type queryType, IEnumerable entities)
{
var results = SerializeDynamicType(queryType);
var objList = AnonymousFns.DeconstructMany(entities, false, queryType).ToList();
var ms = new MemoryStream();
var type = objList.GetType();
var serializer = new DataContractSerializer(type);
using (ms)
{
using (GZipStream compress = new GZipStream(ms, CompressionMode.Compress, CompressionLevel.BestCompression))
{
serializer.WriteObject(compress, objList);
}
}
results.ByteArray = ms.ToArray();
return results;
}
I am confused with this line in particular:
var serializer = new DataContractSerializer(type);
How do you do that in JSON.NET??
THANKS :-)

With JSON.NET, you don't need the type when serializing. I'm assuming that it works out the type you are passing in on its own.
So, you can get rid of this completely:
var type = objList.GetType();
var serializer = new DataContractSerializer(type);
And change this:
serializer.WriteObject(compress, objList);
To:
var json = JsonConvert.SerializeObject(objList);
Here are the JSON.Net docs for JsonConvert.

I believe you can use the BsonWriter to write to a stream. I'm not sure it will give you the exact same binary format you had before, but in concept it is the same.
public SerializedResults SerializeResults(Type queryType, IEnumerable entities)
{
var results = SerializeDynamicType(queryType);
var objList = AnonymousFns.DeconstructMany(entities, false, queryType).ToList();
var ms = new MemoryStream();
using (ms)
{
using (GZipStream compress = new GZipStream(ms, CompressionMode.Compress, CompressionLevel.BestCompression))
{
using( BsonWriter writer = new BsonWriter(compress))
{
JsonSerializer serializer = new JsonSerializer();
serializer.Serialize(writer, objList);
}
}
}
results.ByteArray = ms.ToArray();
return results;
}

Related

FileStreamResult NOT returning file

I have very simple example to export some data to Excel file, in some reason I see the bytes in the response but no file downloaded why?
public async Task<IActionResult> exportRecordsToExcel()
{
var file = await ServiceRequestBL.ExportFO_SrviceRequestToExcel();
return file;
}
public async Task<FileStreamResult> ExportFO_SrviceRequestToExcel()
{
DataTable dt = new DataTable("Grid");
dt.Columns.AddRange(new DataColumn[13] {
new DataColumn("1"), new DataColumn("2"), new DataColumn("g"), new DataColumn("j"), new DataColumn("k"), new DataColumn("l"), new DataColumn("x"), new DataColumn("m"), new DataColumn("9"), new DataColumn("8"), new DataColumn("7"), new DataColumn("6"), new DataColumn("5")});
byte[] data = null;
using (MemoryStream stream = new MemoryStream())
{
IFormatter bf = new BinaryFormatter();
dt.RemotingFormat = SerializationFormat.Binary;
bf.Serialize(stream, dt);
data = stream.ToArray();
}
var memoryStream = new MemoryStream();
memoryStream.Seek(0, SeekOrigin.Begin);
string filename = "Report.xlsx";
return new FileStreamResult(memoryStream, "application/ms-excel") { FileDownloadName = filename };
}
You do not need a using block when using FileStreamResult, as this wrapper will take care of disposing the stream when it is no longer needed (it already uses using internally).
Simply serialize your data into a stream with Serialize(stream, ...) as you have, and pass that stream over to FileStreamResult. Let it take of care of the rest.
You are passing an empty MemoryStream rather than the one you stored the data in
public Task<FileStreamResult> ExportFO_SrviceRequestToExcel()
{
var dt = new DataTable("Grid")
{
RemotingFormat = SerializationFormat.Binary,
Columns =
{
{"1"}, {"2"}, {"g"}, {"j"}, {"k"}, {"l"}, {"x"},
{"m"}, {"9"}, {"8"}, {"7"}, {"6"}, {"5"}
},
};
var stream = new MemoryStream();
var bf = new BinaryFormatter();
bf.Serialize(stream, dt);
memoryStream.Seek(0, SeekOrigin.Begin);
string filename = "Report.xlsx";
return Task.FromResult(new FileStreamResult(memoryStream, "application/ms-excel") { FileDownloadName = filename });
}
The stream does not need a using because FileStreamResult will dispose it, and in any case it's a MemoryStream which is backed only by an array.
Also, in this case there is no need for async as you are not awaiting anything.
I note that BinaryFormatter is deprecated and has security issues. Consider using another serializer if possible.

JsonSerializer size limited to 7168 chars/bytes?

Consider this sample code:
var ms = new MemoryStream();
using (StreamWriter sw = new StreamWriter(ms))
using (JsonWriter writer = new JsonTextWriter(sw))
{
this.GetSerializer().Serialize(writer, data, typeof(T));
// convert stream to string
ms.Position = 0;
var reader = new StreamReader(ms);
var textToSend = reader.ReadToEnd();
}
Serializer obtained from this method:
private JsonSerializer GetSerializer()
{
var serializer = new JsonSerializer
{
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
ContractResolver = new CamelCasePropertyNamesContractResolver()
};
serializer.Converters.Add(new IsoDateTimeConverter { DateTimeFormat = "yyyy-MM-dd\\THH:mm:ss.fffZ" });
return serializer;
}
When I serialize 'data' it produces memory stream with 7168 bytes and when I convert to string I see how message being truncated. Searched but can't find what might be causing this limit?

Deserialize from MemoryStream issue

I need help to figure out how to deserialize from MemoryStream.
var xmlStream = new MemoryStream();
e.Extract(xmlStream);
if (xmlStream != null)
{
TextReader tr = new StreamReader(xmlStream);
var contentItems = new ContentItems();
var serializer = new XmlSerializer(typeof(ContentItems));
contentItems = (ContentItems)serializer.Deserialize(tr); // Error is here
I found the solution
we should add
xmlStream.Seek(0, SeekOrigin.Begin);
so the final code looks like
var xmlStream = new MemoryStream();
e.Extract(xmlStream);
if (xmlStream != null)
{
xmlStream.Seek(0, SeekOrigin.Begin);
var contentItems = new ContentItems();
var serializer = new XmlSerializer(typeof(ContentItems));
contentItems = (ContentItems)serializer.Deserialize(xmlStream); // NO ERROR

DataContractSerializer - how can I output the xml to a string (as opposed to a file)

I had a quick question regarding the datacontractserializer. Maybe it's more of a stream question. I found a piece of code that writes the xml to a filestream. I basically don't want the file and just need the string output.
public static string DataContractSerializeObject<T>(T objectToSerialize)
{
var fs = new FileStream("test.xml", FileMode.OpenOrCreate);
var serializer = new DataContractSerializer(typeof(T));
serializer.WriteObject(fs, objectToSerialize);
fs.Close();
return fs.ToString();
}
fs.ToString() is obviously not what I'm looking for. What stream or writer etc, can I use just to return the proper string and not create a file? I did look at the XML the filestream created and it's exactly what I'm looking for. The XmlSerializer wrote the XML a bit strange and I prefer the output of the DataContractSerializer in this case. Can anyone point me in the right direction?
Something like this - put your output into a MemoryStream and then read that back in:
public static string DataContractSerializeObject<T>(T objectToSerialize)
{
using(MemoryStream memStm = new MemoryStream())
{
var serializer = new DataContractSerializer(typeof(T));
serializer.WriteObject(memStm, objectToSerialize);
memStm.Seek(0, SeekOrigin.Begin);
using(var streamReader = new StreamReader(memStm))
{
string result = streamReader.ReadToEnd();
return result;
}
}
}
Thanks to #xr280xr for pointing out my forgotten StringWriter disposal in the first draft.
/// <summary>
/// Converts this instance to XML.
/// </summary>
/// <returns>XML representing this instance.</returns>
public string ToXml()
{
var serializer = new DataContractSerializer(this.GetType());
using (var output = new StringWriter())
using (var writer = new XmlTextWriter(output) { Formatting = Formatting.Indented })
{
serializer.WriteObject(writer, this);
return output.GetStringBuilder().ToString();
}
}
And even easier:
var serializer = new DataContractSerializer(typeof(T));
var sb = new StringBuilder();
using (var writer = XmlWriter.Create(sb))
{
serializer.WriteObject(writer, objectToSerialize);
writer.Flush();
return sb.ToString();
}
I suggest combining the methods given by Pat and marc_s:
public static string DataContractSerializeObject<T>(T objectToSerialize)
{
using (var output = new StringWriter())
using (var writer = new XmlTextWriter(output) {Formatting = Formatting.Indented})
{
new DataContractSerializer(typeof (T)).WriteObject(writer, objectToSerialize);
return output.GetStringBuilder().ToString();
}
}
A variant of #root's answer:
var serializer = new DataContractSerializer(typeof(T));
var sb = new StringBuilder();
using (var writer = XmlWriter.Create(sb))
{
serializer.WriteObject(writer, objectToSerialize);
}
return sb.ToString();

Deserialize from string instead TextReader

I want to change my code from:
string path = #"c:\Directory\test.xml";
XmlSerializer s = new XmlSerializer(typeof(Car));
TextReader r = new StreamReader(path);
Car car = (Car)s.Deserialize(r);
r.Close();
into code that would convert an XML to a string, and then convert string to the object Car.
Is this possible?
public static string XmlSerializeToString(this object objectInstance)
{
var serializer = new XmlSerializer(objectInstance.GetType());
var sb = new StringBuilder();
using (TextWriter writer = new StringWriter(sb))
{
serializer.Serialize(writer, objectInstance);
}
return sb.ToString();
}
public static T XmlDeserializeFromString<T>(this string objectData)
{
return (T)XmlDeserializeFromString(objectData, typeof(T));
}
public static object XmlDeserializeFromString(this string objectData, Type type)
{
var serializer = new XmlSerializer(type);
object result;
using (TextReader reader = new StringReader(objectData))
{
result = serializer.Deserialize(reader);
}
return result;
}
To use it:
//Make XML
var settings = new ObjectCustomerSettings();
var xmlString = settings.XmlSerializeToString();
//Make Object
var settings = xmlString.XmlDeserializeFromString<ObjectCustomerSettings>();
If you have the XML stored inside a string variable you could use a StringReader:
var xml = #"<car/>";
var serializer = new XmlSerializer(typeof(Car));
using (var reader = new StringReader(xml))
{
var car = (Car)serializer.Deserialize(reader);
}
1-liner, takes a XML string text and YourType as the expected object type. not very different from other answers, just compressed to 1 line:
var result = (YourType)new XmlSerializer(typeof(YourType)).Deserialize(new StringReader(text));
static T DeserializeXml<T>(string sourceXML) where T : class
{
var serializer = new XmlSerializer(typeof(T));
T result = null;
using (TextReader reader = new StringReader(sourceXML))
{
result = (T) serializer.Deserialize(reader);
}
return result;
}
Shamelessly copied from
Generic deserialization of an xml string
public static T DeserializeFromXmlString<T>(string xmlString)
{
var serializer = new XmlSerializer(typeof(T));
using (TextReader reader = new StringReader(xmlString))
{
return (T) serializer.Deserialize(reader);
}
}

Categories

Resources