Related
I have heard that Json.NET is faster than DataContractJsonSerializer, and wanted to give it a try...
But I couldn't find any methods on JsonConvert that take a stream rather than a string.
For deserializing a file containing JSON on WinPhone, for example, I use the following code to read the file contents into a string, and then deserialize into JSON. It appears to be about 4 times slower in my (very ad-hoc) testing than using DataContractJsonSerializer to deserialize straight from the stream...
// DCJS
DataContractJsonSerializer dc = new DataContractJsonSerializer(typeof(Constants));
Constants constants = (Constants)dc.ReadObject(stream);
// JSON.NET
string json = new StreamReader(stream).ReadToEnd();
Constants constants = JsonConvert.DeserializeObject<Constants>(json);
Am I doing it wrong?
The current version of Json.net does not allow you to use the accepted answer code. A current alternative is:
public static object DeserializeFromStream(Stream stream)
{
var serializer = new JsonSerializer();
using (var sr = new StreamReader(stream))
using (var jsonTextReader = new JsonTextReader(sr))
{
return serializer.Deserialize(jsonTextReader);
}
}
Documentation: Deserialize JSON from a file stream
public static void Serialize(object value, Stream s)
{
using (StreamWriter writer = new StreamWriter(s))
using (JsonTextWriter jsonWriter = new JsonTextWriter(writer))
{
JsonSerializer ser = new JsonSerializer();
ser.Serialize(jsonWriter, value);
jsonWriter.Flush();
}
}
public static T Deserialize<T>(Stream s)
{
using (StreamReader reader = new StreamReader(s))
using (JsonTextReader jsonReader = new JsonTextReader(reader))
{
JsonSerializer ser = new JsonSerializer();
return ser.Deserialize<T>(jsonReader);
}
}
UPDATE: This no longer works in the current version, see below for correct answer (no need to vote down, this is correct on older versions).
Use the JsonTextReader class with a StreamReader or use the JsonSerializer overload that takes a StreamReader directly:
var serializer = new JsonSerializer();
serializer.Deserialize(streamReader);
I've written an extension class to help me deserializing from JSON sources (string, stream, file).
public static class JsonHelpers
{
public static T CreateFromJsonStream<T>(this Stream stream)
{
JsonSerializer serializer = new JsonSerializer();
T data;
using (StreamReader streamReader = new StreamReader(stream))
{
data = (T)serializer.Deserialize(streamReader, typeof(T));
}
return data;
}
public static T CreateFromJsonString<T>(this String json)
{
T data;
using (MemoryStream stream = new MemoryStream(System.Text.Encoding.Default.GetBytes(json)))
{
data = CreateFromJsonStream<T>(stream);
}
return data;
}
public static T CreateFromJsonFile<T>(this String fileName)
{
T data;
using (FileStream fileStream = new FileStream(fileName, FileMode.Open))
{
data = CreateFromJsonStream<T>(fileStream);
}
return data;
}
}
Deserializing is now as easy as writing:
MyType obj1 = aStream.CreateFromJsonStream<MyType>();
MyType obj2 = "{\"key\":\"value\"}".CreateFromJsonString<MyType>();
MyType obj3 = "data.json".CreateFromJsonFile<MyType>();
Hope it will help someone else.
I arrived at this question looking for a way to stream an open ended list of objects onto a System.IO.Stream and read them off the other end, without buffering the entire list before sending. (Specifically I'm streaming persisted objects from MongoDB over Web API.)
#Paul Tyng and #Rivers did an excellent job answering the original question, and I used their answers to build a proof of concept for my problem. I decided to post my test console app here in case anyone else is facing the same issue.
using System;
using System.Diagnostics;
using System.IO;
using System.IO.Pipes;
using System.Threading;
using System.Threading.Tasks;
using Newtonsoft.Json;
namespace TestJsonStream {
class Program {
static void Main(string[] args) {
using(var writeStream = new AnonymousPipeServerStream(PipeDirection.Out, HandleInheritability.None)) {
string pipeHandle = writeStream.GetClientHandleAsString();
var writeTask = Task.Run(() => {
using(var sw = new StreamWriter(writeStream))
using(var writer = new JsonTextWriter(sw)) {
var ser = new JsonSerializer();
writer.WriteStartArray();
for(int i = 0; i < 25; i++) {
ser.Serialize(writer, new DataItem { Item = i });
writer.Flush();
Thread.Sleep(500);
}
writer.WriteEnd();
writer.Flush();
}
});
var readTask = Task.Run(() => {
var sw = new Stopwatch();
sw.Start();
using(var readStream = new AnonymousPipeClientStream(pipeHandle))
using(var sr = new StreamReader(readStream))
using(var reader = new JsonTextReader(sr)) {
var ser = new JsonSerializer();
if(!reader.Read() || reader.TokenType != JsonToken.StartArray) {
throw new Exception("Expected start of array");
}
while(reader.Read()) {
if(reader.TokenType == JsonToken.EndArray) break;
var item = ser.Deserialize<DataItem>(reader);
Console.WriteLine("[{0}] Received item: {1}", sw.Elapsed, item);
}
}
});
Task.WaitAll(writeTask, readTask);
writeStream.DisposeLocalCopyOfClientHandle();
}
}
class DataItem {
public int Item { get; set; }
public override string ToString() {
return string.Format("{{ Item = {0} }}", Item);
}
}
}
}
Note that you may receive an exception when the AnonymousPipeServerStream is disposed, I ignored this as it isn't relevant to the problem at hand.
another option that is handy when you are running out of memory is to periodically flush
/// <summary>serialize the value in the stream.</summary>
/// <typeparam name="T">the type to serialize</typeparam>
/// <param name="stream">The stream.</param>
/// <param name="value">The value.</param>
/// <param name="settings">The json settings to use.</param>
/// <param name="bufferSize"></param>
/// <param name="leaveOpen"></param>
public static void JsonSerialize<T>(this Stream stream,[DisallowNull] T value, [DisallowNull] JsonSerializerSettings settings, int bufferSize=1024, bool leaveOpen=false)
{
using (var writer = new StreamWriter(stream,encoding: System.Text.Encoding.UTF32,bufferSize,leaveOpen))
using (var jsonWriter = new JsonTextWriter(writer))
{
var ser = JsonSerializer.Create( settings );
ser.Serialize(jsonWriter, value);
jsonWriter.Flush();
}
}
/// <summary>serialize the value in the stream asynchronously.</summary>
/// <typeparam name="T"></typeparam>
/// <param name="stream">The stream.</param>
/// <param name="value">The value.</param>
/// <param name="settings">The settings.</param>
/// <param name="bufferSize">The buffer size, in bytes, set -1 to not flush till done</param>
/// <param name="leaveOpen"> true to leave the stream open </param>
/// <param name="cancellationToken">Propagates notification that operations should be canceled.</param>
public static Task JsonSerializeAsync<T>(this Stream stream,[DisallowNull] T value, [DisallowNull] JsonSerializerSettings settings, int bufferSize=1024, bool leaveOpen=false, CancellationToken cancellationToken=default)
{
using (var writer = new StreamWriter(stream,encoding: System.Text.Encoding.UTF32,bufferSize: bufferSize,leaveOpen: leaveOpen))
using (var jsonWriter = new JsonTextWriter(writer))
{
var ser = JsonSerializer.Create( settings );
ser.Serialize(jsonWriter, value);
return jsonWriter.Flush();
}
//jsonWriter.FlushAsnc with my version gives an error on the stream
return Task.CompletedTask;
}
You can test/ use it like so:
[TestMethod()]
public void WriteFileIntoJsonTest()
{
var file = new FileInfo(Path.GetTempFileName());
try
{
var list = new HashSet<Guid>();
for (int i = 0; i < 100; i++)
{
list.Add(Guid.NewGuid());
}
file.JsonSerialize(list);
var sr = file.IsValidJson<List<Guid>>(out var result);
Assert.IsTrue(sr);
Assert.AreEqual<int>(list.Count, result.Count);
foreach (var item in result)
{
Assert.IsFalse(list.Add(item), $"The GUID {item} should already exist in the hash set");
}
}
finally
{
file.Refresh();
file.Delete();
}
}
you'd need to create the extension methods, here is the whole set:
public static class JsonStreamReaderExt
{
static JsonSerializerSettings _settings ;
static JsonStreamReaderExt()
{
_settings = JsonConvert.DefaultSettings?.Invoke() ?? new JsonSerializerSettings();
_settings.ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor;
_settings.DateTimeZoneHandling = DateTimeZoneHandling.Utc;
_settings.DateFormatHandling = DateFormatHandling.IsoDateFormat ;
}
/// <summary>
/// serialize the value in the stream.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="stream">The stream.</param>
/// <param name="value">The value.</param>
public static void JsonSerialize<T>(this Stream stream,[DisallowNull] T value)
{
stream.JsonSerialize(value,_settings);
}
/// <summary>
/// serialize the value in the file .
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="file">The file.</param>
/// <param name="value">The value.</param>
public static void JsonSerialize<T>(this FileInfo file,[DisallowNull] T value)
{
if (string.IsNullOrEmpty(file.DirectoryName)==true && Directory.Exists(file.DirectoryName) == false)
{
Directory.CreateDirectory(file.FullName);
}
using var s = file.OpenWrite();
s.JsonSerialize(value, _settings);
file.Refresh();
}
/// <summary>
/// serialize the value in the file .
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="file">The file.</param>
/// <param name="value">The value.</param>
/// <param name="settings">the json settings to use</param>
public static void JsonSerialize<T>(this FileInfo file, [DisallowNull] T value, [DisallowNull] JsonSerializerSettings settings)
{
if (string.IsNullOrEmpty(file.DirectoryName) == true && Directory.Exists(file.DirectoryName) == false)
{
Directory.CreateDirectory(file.FullName);
}
using var s = file.OpenWrite();
s.JsonSerialize(value, settings);
file.Refresh();
}
/// <summary>
/// serialize the value in the file .
/// </summary>
/// <remarks>File will be refreshed to contain the new meta data</remarks>
/// <typeparam name="T">the type to serialize</typeparam>
/// <param name="file">The file.</param>
/// <param name="value">The value.</param>
/// <param name="cancellationToken">Propagates notification that operations should be canceled.</param>
public static async Task JsonSerializeAsync<T>(this FileInfo file, [DisallowNull] T value, CancellationToken cancellationToken = default)
{
if (string.IsNullOrEmpty(file.DirectoryName) == true && Directory.Exists(file.DirectoryName) == false)
{
Directory.CreateDirectory(file.FullName);
}
using (var stream = file.OpenWrite())
{
await stream.JsonSerializeAsync(value, _settings,bufferSize:1024,leaveOpen:false, cancellationToken).ConfigureAwait(false);
}
file.Refresh();
}
/// <summary>
/// serialize the value in the file .
/// </summary>
/// <remarks>File will be refreshed to contain the new meta data</remarks>
/// <typeparam name="T">the type to serialize</typeparam>
/// <param name="file">The file to create or overwrite.</param>
/// <param name="value">The value.</param>
/// <param name="settings">the json settings to use</param>
/// <param name="cancellationToken">Propagates notification that operations should be canceled.</param>
public static async Task JsonSerializeAsync<T>(this FileInfo file, [DisallowNull] T value, [DisallowNull] JsonSerializerSettings settings, CancellationToken cancellationToken=default)
{
if (string.IsNullOrEmpty(file.DirectoryName) == true && Directory.Exists(file.DirectoryName) == false)
{
Directory.CreateDirectory(file.FullName);
}
using (var stream = file.OpenWrite())
{
await stream.JsonSerializeAsync(value, settings,bufferSize:1024,leaveOpen:false, cancellationToken).ConfigureAwait(false);
}
file.Refresh();
}
/// <summary>serialize the value in the stream.</summary>
/// <typeparam name="T">the type to serialize</typeparam>
/// <param name="stream">The stream.</param>
/// <param name="value">The value.</param>
/// <param name="settings">The json settings to use.</param>
/// <param name="bufferSize">The buffer size, in bytes, set -1 to not flush till done</param>
/// <param name="leaveOpen"> true to leave the stream open </param>
public static void JsonSerialize<T>(this Stream stream,[DisallowNull] T value, [DisallowNull] JsonSerializerSettings settings, int bufferSize=1024, bool leaveOpen=false)
{
using (var writer = new StreamWriter(stream,encoding: System.Text.Encoding.UTF32,bufferSize,leaveOpen))
using (var jsonWriter = new JsonTextWriter(writer))
{
var ser = JsonSerializer.Create( settings );
ser.Serialize(jsonWriter, value);
jsonWriter.Flush();
}
}
/// <summary>serialize the value in the stream asynchronously.</summary>
/// <typeparam name="T"></typeparam>
/// <param name="stream">The stream.</param>
/// <param name="value">The value.</param>
/// <param name="settings">The settings.</param>
/// <param name="bufferSize">The buffer size, in bytes, set -1 to not flush till done</param>
/// <param name="leaveOpen"> true to leave the stream open </param>
/// <param name="cancellationToken">Propagates notification that operations should be canceled.</param>
public static Task JsonSerializeAsync<T>(this Stream stream,[DisallowNull] T value, [DisallowNull] JsonSerializerSettings settings, int bufferSize=1024, bool leaveOpen=false, CancellationToken cancellationToken=default)
{
using (var writer = new StreamWriter(stream,encoding: System.Text.Encoding.UTF32,bufferSize: bufferSize,leaveOpen: leaveOpen))
using (var jsonWriter = new JsonTextWriter(writer))
{
var ser = JsonSerializer.Create( settings );
ser.Serialize(jsonWriter, value);
jsonWriter.Flush();
}
return Task.CompletedTask;
}
/// <summary>
/// Determines whether [is valid json] [the specified result].
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="stream">The stream.</param>
/// <param name="result">The result.</param>
/// <returns><c>true</c> if [is valid json] [the specified result]; otherwise, <c>false</c>.</returns>
public static bool IsValidJson<T>(this Stream stream, [NotNullWhen(true)] out T? result)
{
if (stream is null)
{
throw new ArgumentNullException(nameof(stream));
}
if (stream.Position != 0)
{
stream.Seek(0, SeekOrigin.Begin);
}
JsonSerializerSettings settings = (JsonConvert.DefaultSettings?.Invoke()) ?? new JsonSerializerSettings() { DateTimeZoneHandling = DateTimeZoneHandling.Utc, DateFormatHandling = DateFormatHandling.IsoDateFormat };
settings.ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor;
using (var reader = new StreamReader(stream))
using (var jsonReader = new JsonTextReader(reader))
{
var ser = JsonSerializer.Create(settings);
try
{
result = ser.Deserialize<T>(jsonReader);
}
catch { result = default; }
}
return result is not null;
}
/// <summary>
/// Determines whether [is valid json] [the specified settings].
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="stream">The stream.</param>
/// <param name="settings">The settings.</param>
/// <param name="result">The result.</param>
/// <returns><c>true</c> if [is valid json] [the specified settings]; otherwise, <c>false</c>.</returns>
public static bool IsValidJson<T>(this Stream stream, JsonSerializerSettings settings, [NotNullWhen(true)] out T? result)
{
if (stream is null)
{
throw new ArgumentNullException(nameof(stream));
}
if (settings is null)
{
throw new ArgumentNullException(nameof(settings));
}
if (stream.Position != 0)
{
stream.Seek(0, SeekOrigin.Begin);
}
using (var reader = new StreamReader(stream))
using (var jsonReader = new JsonTextReader(reader))
{
var ser = JsonSerializer.Create(settings);
try
{
result = ser.Deserialize<T>(jsonReader);
}
catch { result = default; }
}
return result is not null;
}
/// <summary>
/// Determines whether file contains valid json using the specified settings and reads it into the output.
/// </summary>
/// <typeparam name="T">Type to convert into</typeparam>
/// <param name="file">The file.</param>
/// <param name="settings">The settings.</param>
/// <param name="result">The result.</param>
/// <returns><c>true</c> if [is valid json] [the specified settings]; otherwise, <c>false</c>.</returns>
/// <exception cref="System.ArgumentNullException">file</exception>
/// <exception cref="System.ArgumentNullException"></exception>
/// <exception cref="System.ArgumentNullException">settings</exception>
/// <exception cref="System.IO.FileNotFoundException">File could not be accessed</exception>
public static bool IsValidJson<T>(this FileInfo file, JsonSerializerSettings settings, [NotNullWhen(true)] out T? result)
{
if (file is null)
{
throw new ArgumentNullException(nameof(file));
}
if (File.Exists(file.FullName) == false)
{
throw new FileNotFoundException("File could not be accessed",fileName: file.FullName);
}
using var stream = file.OpenRead();
if (stream is null)
{
throw new ArgumentNullException(message:"Could not open the file and access the underlying file stream",paramName: nameof(file));
}
if (settings is null)
{
throw new ArgumentNullException(nameof(settings));
}
using (var reader = new StreamReader(stream))
using (var jsonReader = new JsonTextReader(reader))
{
var ser = JsonSerializer.Create(settings);
try
{
result = ser.Deserialize<T>(jsonReader);
}
catch { result = default; }
}
return result is not null;
}
/// <summary>
/// Determines whether file contains valid json using the specified settings and reads it into the output.
/// </summary>
/// <typeparam name="T">Type to convert into</typeparam>
/// <param name="file">The file.</param>
/// <param name="result">The result.</param>
/// <returns><c>true</c> if [is valid json] [the specified result]; otherwise, <c>false</c>.</returns>
/// <exception cref="System.ArgumentNullException">file</exception>
/// <exception cref="System.IO.FileNotFoundException">File could not be accessed</exception>
public static bool IsValidJson<T>(this FileInfo file, [NotNullWhen(true)] out T? result)
{
if (file is null)
{
throw new ArgumentNullException(nameof(file));
}
if (File.Exists(file.FullName) == false)
{
throw new FileNotFoundException("File could not be accessed",fileName: file.FullName);
}
JsonSerializerSettings settings =( JsonConvert.DefaultSettings?.Invoke()) ?? new JsonSerializerSettings() { DateTimeZoneHandling= DateTimeZoneHandling.Utc, DateFormatHandling= DateFormatHandling.IsoDateFormat };
settings.ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor;
return file.IsValidJson<T>(settings,out result);
}
}
Context
I'm trying to understand how to use Serialization, never used it previously.
Right now I have a populate method in my singleton object (Main class) that basically adds a few member objects to a list of members using my addMember methods
I want to serialize this Members List Once I can serialize and deserialize the list I can delete my populate method.
Questions
HOW do I serialize this list so that the members list is deserialized upon startup?
WHERE do I serialize specifically? Do I serialize when I'm creating a new member, or do I just serialize the list at shutdown and deserialize at startup.
Since member information can be edited, how do I serialize the updates and overwrite the previously held data?
Code Listings
I'm kinda new to Serialization, but here's my code, I'm using a method for this because I I think it's cleaner this way, using ISerializable in my main class. Here's a few snippets from my main class, keep in mind I have tons of comments in my code, that's kinda why I didn't post this previously:
namespace HillRacingGraded
{
[Serializable]
public class HillRacing : ISerializable
{
/// <summary>
/// Singleton object hillracing
/// </summary>
private static HillRacing hillracing;
GUIUtility gui = new GUIUtility();
/// <summary>
/// Instance property returns the singleton instance
/// </summary>
public static HillRacing Instance
{
get
{
if (hillracing == null)
hillracing = new HillRacing();
return hillracing;
}
}
/// <summary>
/// public Property that returns races list, can be accessed by other classes.
/// </summary>
public List<BaseRace> Races
{
get
{
return races;
}
set
{
races = value;
}
}
/// <summary>
/// public Property that returns members list, can be accessed by other classes.
/// </summary>
public List<BaseMember> Members
{
get
{
return members;
}
set
{
members = value;
}
}
/// <summary>
/// instantiate the list of members
/// </summary>
private List<BaseMember> members; //I WANT TO SERIALIZE THIS
/// <summary>
/// instantiate the list of races
/// </summary>
private List<BaseRace> races; //I WANT TO SERIALIZE THIS
/// <summary>
/// Default constructor for hillracing.
/// </summary>
public HillRacing()
{
//members is a new list of the BaseMember objects.
//races is a new list of the BaseRace objects.
members = new List<BaseMember>();
races = new List<BaseRace>();
//call the populate method on launch, mostly for testing purposes.
Populate();
}
/// <summary>
/// Hillracing constructor for serialization
/// </summary>
/// <param name="info"></param>
/// <param name="ctxt"></param>
public HillRacing(SerializationInfo info, StreamingContext ctxt)
{
this.members = (List<BaseMember>)info.GetValue("Members", typeof(List<BaseMember>));
this.races = (List<BaseRace>)info.GetValue("Races", typeof(List<BaseRace>));
}
/// <summary>
/// get object data
/// </summary>
/// <param name="info"></param>
/// <param name="ctxt"></param>
public void GetObjectData(SerializationInfo info, StreamingContext ctxt)
{
info.AddValue("Members", this.members);
}
/// <summary>
/// Adds a new junior member to the list of all members.
/// </summary>
/// <param name="stringfirstname">first name of the member</param>
/// <param name="stringlastname">last name of the member</param>
/// <param name="stringmiddlename">middle name of the member</param>
/// <param name="stringtitle">title of the member</param>
/// <param name="strst">street of the member</param>
/// <param name="strtwn">Town of the member</param>
/// <param name="strpc">Postcode of the member</param>
/// <param name="strEmail">email of the member</param>
/// <param name="intMobile">Mobile of the member</param>
/// <param name="intHome">Home phone of the member</param>
/// <param name="shrnumber">ID number of the member</param>
/// <param name="memtype">Type of the member</param>
/// <param name="username">username of the member</param>
/// <param name="noracesrun">number of races that the member has run</param>
/// <param name="perraceswon">percentage of races that the member has won</param>
/// <param name="mempic">image of the member</param>
/// <param name="memclub">the club the member is part of</param>
/// <param name="gender">the gender of the member</param>
/// <param name="memexp">the experience level the member has</param>
/// <param name="yearofbirth">the year of birth the member was born in</param>
/// <param name="monthofbirth">the month of birth the member was born in</param>
/// <param name="dayofbirth">the day of birth the member was born on</param>
public void addJunior(string stringfirstname, string stringlastname, string stringmiddlename, string stringtitle, string strst, string strtwn, string strpc, string strEmail, int intMobile, int intHome,
string shrnumber, string memtype, string username, string password, int noracesrun, float perraceswon, string mempic, string memclub, string gender, int memexp, int yearofbirth, int monthofbirth, int dayofbirth, string nextofkin, string docName, string docTel, string healthIssues, string parentalConsent)
{
// create a new member with the entered parameters to add to the list.
JuniorMember newMember = new JuniorMember(stringfirstname, stringlastname, stringmiddlename, stringtitle, strst, strtwn, strpc, strEmail, intMobile, intHome, shrnumber, memtype, username, password, noracesrun, perraceswon, mempic, memclub, gender, memexp, yearofbirth, monthofbirth, dayofbirth,nextofkin,docName,docTel,healthIssues,parentalConsent);
//use add functionality of list to add to the list.
members.Add(newMember);
}
/// <summary>
///
/// </summary>
/// <param name="stringfirstname">first name of the member</param>
/// <param name="stringlastname">last name of the member</param>
/// <param name="stringmiddlename">middle name of the member</param>
/// <param name="stringtitle">title of the member</param>
/// <param name="strst">street of the member</param>
/// <param name="strtwn">Town of the member</param>
/// <param name="strpc">Postcode of the member</param>
/// <param name="strEmail">email of the member</param>
/// <param name="intMobile">Mobile of the member</param>
/// <param name="intHome">Home phone of the member</param>
/// <param name="shrnumber">ID number of the member</param>
/// <param name="memtype">Type of the member</param>
/// <param name="username">username of the member</param>
/// <param name="noracesrun">number of races that the member has run</param>
/// <param name="perraceswon">percentage of races that the member has won</param>
/// <param name="mempic">image of the member</param>
/// <param name="memclub">the club the member is part of</param>
/// <param name="gender">the gender of the member</param>
/// <param name="memexp">the experience level the member has</param>
/// <param name="yearofbirth">the year of birth the member was born in</param>
/// <param name="monthofbirth">the month of birth the member was born in</param>
/// <param name="dayofbirth">the day of birth the member was born on</param>
/// <param name="nextofkin">The next family member contact</param>
/// <param name="docName">The name of the members doctor</param>
/// <param name="docTel">A telephone number for the doctor</param>
/// <param name="healthIssues">the health issues this member has.</param>
public void addSenior(string stringfirstname, string stringlastname, string stringmiddlename, string stringtitle, string strst, string strtwn, string strpc, string strEmail, int intMobile, int intHome,
string shrnumber, string memtype, string username, string password, int noracesrun, float perraceswon, string mempic, string memclub, string gender, int memexp, int yearofbirth, int monthofbirth, int dayofbirth, string nextofkin, string docName, string docTel, string healthIssues)
{
//create a new member with the entered parameters to add to the list.
SeniorMember newMember = new SeniorMember(stringfirstname, stringlastname, stringmiddlename, stringtitle, strst, strtwn, strpc, strEmail, intMobile, intHome, shrnumber, memtype, username, password, noracesrun, perraceswon, mempic, memclub, gender, memexp, yearofbirth, monthofbirth, dayofbirth,docName,docTel,healthIssues);
//use standard list functionality of list to add this new member to the list.
members.Add(newMember);
}
Here is my Serialization method in the Serializer class:
public void SerializeObject(string filename, object objectToSerialize)
{
Stream stream = File.Open(filename + ".bin", FileMode.Create);
BinaryFormatter bFormatter = new BinaryFormatter();
bFormatter.Serialize(stream, objectToSerialize);
stream.Close();
}
Problem is, I don't know how to actually use this.
Also have a deserializer:
public HillRacing DeSerializeObject(string filename)
{
HillRacing hillracing;
Stream stream = File.Open(filename + ".bin", FileMode.Open);
BinaryFormatter bFormatter = new BinaryFormatter();
hillracing = (HillRacing)bFormatter.Deserialize(stream);
stream.Close();
return hillracing;
}
Although you have done most of the part i suggest a little generics make it multiuse as
public static class StreamUtilities
{
public static T GetObject<T>(Byte[] rawimage) where T : class
{
try
{
MemoryStream memStream = new MemoryStream();
BinaryFormatter binForm = new BinaryFormatter();
memStream.Write(rawimage, 0, rawimage.Length);
memStream.Seek(0, SeekOrigin.Begin);
return binForm.Deserialize(memStream) as T;
}
catch (Exception ex)
{
return null;
}
}
public static Byte[] Serialize<T>(this T obj) where T:class
{
if (obj == null)
return null;
BinaryFormatter bf = new BinaryFormatter();
MemoryStream ms = new MemoryStream();
bf.Serialize(ms, obj);
return ms.ToArray();
}
}
then in your main class or whereever you want it to use include to namespace where the above extention method is then use
Object1 a=new Object1();// any serializable object
serializedbytes=a.Serialize<Object1>();
//deserialize
Object b=StreamUtilities.GetObject<Object1>(serializedbytes);
The above extention method will allow to seriailize/Deserialize any serializable Object.
I have a list of objects and I need to save that somewhere in my computer. I have read some forums and I know that the object has to be Serializable. But it would be nice if I can get an example. For example if I have the following:
[Serializable]
public class SomeClass
{
public string someProperty { get; set; }
}
SomeClass object1 = new SomeClass { someProperty = "someString" };
But how can I store object1 somewhere in my computer and later retrieve?
I just wrote a blog post on saving an object's data to Binary, XML, or Json. You are correct that you must decorate your classes with the [Serializable] attribute, but only if you are using Binary serialization. You may prefer to use XML or Json serialization. Here are the functions to do it in the various formats. See my blog post for more details.
Binary
/// <summary>
/// Writes the given object instance to a binary file.
/// <para>Object type (and all child types) must be decorated with the [Serializable] attribute.</para>
/// <para>To prevent a variable from being serialized, decorate it with the [NonSerialized] attribute; cannot be applied to properties.</para>
/// </summary>
/// <typeparam name="T">The type of object being written to the binary file.</typeparam>
/// <param name="filePath">The file path to write the object instance to.</param>
/// <param name="objectToWrite">The object instance to write to the binary file.</param>
/// <param name="append">If false the file will be overwritten if it already exists. If true the contents will be appended to the file.</param>
public static void WriteToBinaryFile<T>(string filePath, T objectToWrite, bool append = false)
{
using (Stream stream = File.Open(filePath, append ? FileMode.Append : FileMode.Create))
{
var binaryFormatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
binaryFormatter.Serialize(stream, objectToWrite);
}
}
/// <summary>
/// Reads an object instance from a binary file.
/// </summary>
/// <typeparam name="T">The type of object to read from the binary file.</typeparam>
/// <param name="filePath">The file path to read the object instance from.</param>
/// <returns>Returns a new instance of the object read from the binary file.</returns>
public static T ReadFromBinaryFile<T>(string filePath)
{
using (Stream stream = File.Open(filePath, FileMode.Open))
{
var binaryFormatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
return (T)binaryFormatter.Deserialize(stream);
}
}
XML
Requires the System.Xml assembly to be included in your project.
/// <summary>
/// Writes the given object instance to an XML file.
/// <para>Only Public properties and variables will be written to the file. These can be any type though, even other classes.</para>
/// <para>If there are public properties/variables that you do not want written to the file, decorate them with the [XmlIgnore] attribute.</para>
/// <para>Object type must have a parameterless constructor.</para>
/// </summary>
/// <typeparam name="T">The type of object being written to the file.</typeparam>
/// <param name="filePath">The file path to write the object instance to.</param>
/// <param name="objectToWrite">The object instance to write to the file.</param>
/// <param name="append">If false the file will be overwritten if it already exists. If true the contents will be appended to the file.</param>
public static void WriteToXmlFile<T>(string filePath, T objectToWrite, bool append = false) where T : new()
{
TextWriter writer = null;
try
{
var serializer = new XmlSerializer(typeof(T));
writer = new StreamWriter(filePath, append);
serializer.Serialize(writer, objectToWrite);
}
finally
{
if (writer != null)
writer.Close();
}
}
/// <summary>
/// Reads an object instance from an XML file.
/// <para>Object type must have a parameterless constructor.</para>
/// </summary>
/// <typeparam name="T">The type of object to read from the file.</typeparam>
/// <param name="filePath">The file path to read the object instance from.</param>
/// <returns>Returns a new instance of the object read from the XML file.</returns>
public static T ReadFromXmlFile<T>(string filePath) where T : new()
{
TextReader reader = null;
try
{
var serializer = new XmlSerializer(typeof(T));
reader = new StreamReader(filePath);
return (T)serializer.Deserialize(reader);
}
finally
{
if (reader != null)
reader.Close();
}
}
Json
You must include a reference to Newtonsoft.Json assembly, which can be obtained from the Json.NET NuGet Package.
/// <summary>
/// Writes the given object instance to a Json file.
/// <para>Object type must have a parameterless constructor.</para>
/// <para>Only Public properties and variables will be written to the file. These can be any type though, even other classes.</para>
/// <para>If there are public properties/variables that you do not want written to the file, decorate them with the [JsonIgnore] attribute.</para>
/// </summary>
/// <typeparam name="T">The type of object being written to the file.</typeparam>
/// <param name="filePath">The file path to write the object instance to.</param>
/// <param name="objectToWrite">The object instance to write to the file.</param>
/// <param name="append">If false the file will be overwritten if it already exists. If true the contents will be appended to the file.</param>
public static void WriteToJsonFile<T>(string filePath, T objectToWrite, bool append = false) where T : new()
{
TextWriter writer = null;
try
{
var contentsToWriteToFile = JsonConvert.SerializeObject(objectToWrite);
writer = new StreamWriter(filePath, append);
writer.Write(contentsToWriteToFile);
}
finally
{
if (writer != null)
writer.Close();
}
}
/// <summary>
/// Reads an object instance from an Json file.
/// <para>Object type must have a parameterless constructor.</para>
/// </summary>
/// <typeparam name="T">The type of object to read from the file.</typeparam>
/// <param name="filePath">The file path to read the object instance from.</param>
/// <returns>Returns a new instance of the object read from the Json file.</returns>
public static T ReadFromJsonFile<T>(string filePath) where T : new()
{
TextReader reader = null;
try
{
reader = new StreamReader(filePath);
var fileContents = reader.ReadToEnd();
return JsonConvert.DeserializeObject<T>(fileContents);
}
finally
{
if (reader != null)
reader.Close();
}
}
Example
// Write the contents of the variable someClass to a file.
WriteToBinaryFile<SomeClass>("C:\someClass.txt", object1);
// Read the file contents back into a variable.
SomeClass object1= ReadFromBinaryFile<SomeClass>("C:\someClass.txt");
You can use the following:
/// <summary>
/// Serializes an object.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="serializableObject"></param>
/// <param name="fileName"></param>
public void SerializeObject<T>(T serializableObject, string fileName)
{
if (serializableObject == null) { return; }
try
{
XmlDocument xmlDocument = new XmlDocument();
XmlSerializer serializer = new XmlSerializer(serializableObject.GetType());
using (MemoryStream stream = new MemoryStream())
{
serializer.Serialize(stream, serializableObject);
stream.Position = 0;
xmlDocument.Load(stream);
xmlDocument.Save(fileName);
}
}
catch (Exception ex)
{
//Log exception here
}
}
/// <summary>
/// Deserializes an xml file into an object list
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="fileName"></param>
/// <returns></returns>
public T DeSerializeObject<T>(string fileName)
{
if (string.IsNullOrEmpty(fileName)) { return default(T); }
T objectOut = default(T);
try
{
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.Load(fileName);
string xmlString = xmlDocument.OuterXml;
using (StringReader read = new StringReader(xmlString))
{
Type outType = typeof(T);
XmlSerializer serializer = new XmlSerializer(outType);
using (XmlReader reader = new XmlTextReader(read))
{
objectOut = (T)serializer.Deserialize(reader);
}
}
}
catch (Exception ex)
{
//Log exception here
}
return objectOut;
}
You'll need to serialize to something: that is, pick binary, or xml (for default serializers) or write custom serialization code to serialize to some other text form.
Once you've picked that, your serialization will (normally) call a Stream that is writing to some kind of file.
So, with your code, if I were using XML Serialization:
var path = #"C:\Test\myserializationtest.xml";
using(FileStream fs = new FileStream(path, FileMode.Create))
{
XmlSerializer xSer = new XmlSerializer(typeof(SomeClass));
xSer.Serialize(fs, serializableObject);
}
Then, to deserialize:
using(FileStream fs = new FileStream(path, FileMode.Open)) //double check that...
{
XmlSerializer _xSer = new XmlSerializer(typeof(SomeClass));
var myObject = _xSer.Deserialize(fs);
}
NOTE: This code hasn't been compiled, let alone run- there may be some errors. Also, this assumes completely out-of-the-box serialization/deserialization. If you need custom behavior, you'll need to do additional work.
1. Restore Object From File
From Here you can deserialize an object from file in two way.
Solution-1: Read file into a string and deserialize JSON to a type
string json = File.ReadAllText(#"c:\myObj.json");
MyObject myObj = JsonConvert.DeserializeObject<MyObject>(json);
Solution-2: Deserialize JSON directly from a file
using (StreamReader file = File.OpenText(#"c:\myObj.json"))
{
JsonSerializer serializer = new JsonSerializer();
MyObject myObj2 = (MyObject)serializer.Deserialize(file, typeof(MyObject));
}
2. Save Object To File
from here you can serialize an object to file in two way.
Solution-1: Serialize JSON to a string and then write string to a file
string json = JsonConvert.SerializeObject(myObj);
File.WriteAllText(#"c:\myObj.json", json);
Solution-2: Serialize JSON directly to a file
using (StreamWriter file = File.CreateText(#"c:\myObj.json"))
{
JsonSerializer serializer = new JsonSerializer();
serializer.Serialize(file, myObj);
}
3. Extra
You can download Newtonsoft.Json from NuGet by following command
Install-Package Newtonsoft.Json
You can use JsonConvert from Newtonsoft library.
To serialize an object and write to a file in json format:
File.WriteAllText(filePath, JsonConvert.SerializeObject(obj));
And to deserialize it back into object:
var obj = JsonConvert.DeserializeObject<ObjType>(File.ReadAllText(filePath));
**1. Convert the json string to base64string and Write or append it to binary file.
2. Read base64string from binary file and deserialize using BsonReader.
**
public static class BinaryJson
{
public static string SerializeToBase64String(this object obj)
{
JsonSerializer jsonSerializer = new JsonSerializer();
MemoryStream objBsonMemoryStream = new MemoryStream();
using (BsonWriter bsonWriterObject = new BsonWriter(objBsonMemoryStream))
{
jsonSerializer.Serialize(bsonWriterObject, obj);
return Convert.ToBase64String(objBsonMemoryStream.ToArray());
}
//return Encoding.ASCII.GetString(objBsonMemoryStream.ToArray());
}
public static T DeserializeToObject<T>(this string base64String)
{
byte[] data = Convert.FromBase64String(base64String);
MemoryStream ms = new MemoryStream(data);
using (BsonReader reader = new BsonReader(ms))
{
JsonSerializer serializer = new JsonSerializer();
return serializer.Deserialize<T>(reader);
}
}
}
I have got the following code:
BaseContent.cs
public class BaseContent
{
// Some auto properties
}
News.cs
public class News : BaseContent
{
// Some more auto properties
}
Events.cs
public class Event : BaseContent
{
// Some more auto properites
}
GenericResponse.cs
public class GenericResponse<T>
{
[XmlArray("Content")]
[XmlArrayItem("NewsObject", typeof(News)]
[XmlArrayItem("EventObject", typeof(Event)]
public List<T> ContentItems { get; set; }
}
NewsResponse.cs
public class NewsResponse : GenericResponse<News> {}
EventResponse.cs
public class EventResponse : GenericResponse<Event> {}
As you can see, I have a base class BaseContent and two classes deriving from it. Next I have a generic response class, since the structure of the xml-files is always the same, but they differ in some properties.
I thought I can specify with the [XmlArrayItem] which name to use for a specific class. But now I get the error:
System.InvalidOperationException: Unable to generate a temporary class (result=1).
error CS0012: The type 'System.Object' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Runtime, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'.
I can not add this reference, because I'm working on a Windows 8 App.
If I comment out one of the [XmlArrayItem] it is working well.
Anyone got an idea to solve this problem?
Update
I can not use DataContractSerializer, because I have to use XmlAttributes
Edit: Feel free to download the demo project
You didn't provide all the properties for the objects, so allow me to add some - just as an example:
public class BaseContent
{
[XmlAttribute("Name")]
public string Name { get; set; }
}
[XmlType(TypeName = "EventObject")]
public class Event : BaseContent
{
[XmlAttribute("EventId")]
public int EventId { get; set; }
}
[XmlType(TypeName = "NewsObject")]
public class News : BaseContent
{
[XmlAttribute("NewsId")]
public int NewsId { get; set; }
}
GenericResponse.cs could be defined this way - no need to specify the typeof for the array items:
public class GenericResponse<T>
{
[XmlArray("Content")]
public List<T> ContentItems { get; set; }
public GenericResponse()
{
this.ContentItems = new List<T>();
}
}
And then you have the response classes:
public class EventResponse : GenericResponse<Event>
{
}
public class NewsResponse : GenericResponse<News>
{
}
Example 1: Serialize an EventResponse object
var response = new EventResponse
{
ContentItems = new List<Event>
{
new Event {
EventId = 1,
Name = "Event 1"
},
new Event {
EventId = 2,
Name = "Event 2"
}
}
};
string xml = XmlSerializer<EventResponse>.Serialize(response);
Output XML:
<?xml version="1.0" encoding="utf-8"?>
<EventResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Content>
<EventObject Name="Event 1" EventId="1" />
<EventObject Name="Event 2" EventId="2" />
</Content>
</EventResponse>
If you try the same with NewsResponse it will work fine. BTW I'm using my generic XmlSerializer, click on the link to know more about it.
XmlSerializer.cs:
/// <summary>
/// XML serializer helper class. Serializes and deserializes objects from/to XML
/// </summary>
/// <typeparam name="T">The type of the object to serialize/deserialize.
/// Must have a parameterless constructor and implement <see cref="Serializable"/></typeparam>
public class XmlSerializer<T> where T: class, new()
{
/// <summary>
/// Deserializes a XML string into an object
/// Default encoding: <c>UTF8</c>
/// </summary>
/// <param name="xml">The XML string to deserialize</param>
/// <returns>An object of type <c>T</c></returns>
public static T Deserialize(string xml)
{
return Deserialize(xml, Encoding.UTF8, null);
}
/// <summary>
/// Deserializes a XML string into an object
/// Default encoding: <c>UTF8</c>
/// </summary>
/// <param name="xml">The XML string to deserialize</param>
/// <param name="encoding">The encoding</param>
/// <returns>An object of type <c>T</c></returns>
public static T Deserialize(string xml, Encoding encoding)
{
return Deserialize(xml, encoding, null);
}
/// <summary>
/// Deserializes a XML string into an object
/// </summary>
/// <param name="xml">The XML string to deserialize</param>
/// <param name="settings">XML serialization settings. <see cref="System.Xml.XmlReaderSettings"/></param>
/// <returns>An object of type <c>T</c></returns>
public static T Deserialize(string xml, XmlReaderSettings settings)
{
return Deserialize(xml, Encoding.UTF8, settings);
}
/// <summary>
/// Deserializes a XML string into an object
/// </summary>
/// <param name="xml">The XML string to deserialize</param>
/// <param name="encoding">The encoding</param>
/// <param name="settings">XML serialization settings. <see cref="System.Xml.XmlReaderSettings"/></param>
/// <returns>An object of type <c>T</c></returns>
public static T Deserialize(string xml, Encoding encoding, XmlReaderSettings settings)
{
if (string.IsNullOrEmpty(xml))
throw new ArgumentException("XML cannot be null or empty", "xml");
XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
using (MemoryStream memoryStream = new MemoryStream(encoding.GetBytes(xml)))
{
using (XmlReader xmlReader = XmlReader.Create(memoryStream, settings))
{
return (T) xmlSerializer.Deserialize(xmlReader);
}
}
}
/// <summary>
/// Deserializes a XML file.
/// </summary>
/// <param name="filename">The filename of the XML file to deserialize</param>
/// <returns>An object of type <c>T</c></returns>
public static T DeserializeFromFile(string filename)
{
return DeserializeFromFile(filename, new XmlReaderSettings());
}
/// <summary>
/// Deserializes a XML file.
/// </summary>
/// <param name="filename">The filename of the XML file to deserialize</param>
/// <param name="settings">XML serialization settings. <see cref="System.Xml.XmlReaderSettings"/></param>
/// <returns>An object of type <c>T</c></returns>
public static T DeserializeFromFile(string filename, XmlReaderSettings settings)
{
if (string.IsNullOrEmpty(filename))
throw new ArgumentException("filename", "XML filename cannot be null or empty");
if (! File.Exists(filename))
throw new FileNotFoundException("Cannot find XML file to deserialize", filename);
// Create the stream writer with the specified encoding
using (XmlReader reader = XmlReader.Create(filename, settings))
{
System.Xml.Serialization.XmlSerializer xmlSerializer = new System.Xml.Serialization.XmlSerializer(typeof(T));
return (T) xmlSerializer.Deserialize(reader);
}
}
/// <summary>
/// Serialize an object
/// </summary>
/// <param name="source">The object to serialize</param>
/// <returns>A XML string that represents the object to be serialized</returns>
public static string Serialize(T source)
{
// indented XML by default
return Serialize(source, null, GetIndentedSettings());
}
/// <summary>
/// Serialize an object
/// </summary>
/// <param name="source">The object to serialize</param>
/// <param name="namespaces">Namespaces to include in serialization</param>
/// <returns>A XML string that represents the object to be serialized</returns>
public static string Serialize(T source, XmlSerializerNamespaces namespaces)
{
// indented XML by default
return Serialize(source, namespaces, GetIndentedSettings());
}
/// <summary>
/// Serialize an object
/// </summary>
/// <param name="source">The object to serialize</param>
/// <param name="settings">XML serialization settings. <see cref="System.Xml.XmlWriterSettings"/></param>
/// <returns>A XML string that represents the object to be serialized</returns>
public static string Serialize(T source, XmlWriterSettings settings)
{
return Serialize(source, null, settings);
}
/// <summary>
/// Serialize an object
/// </summary>
/// <param name="source">The object to serialize</param>
/// <param name="namespaces">Namespaces to include in serialization</param>
/// <param name="settings">XML serialization settings. <see cref="System.Xml.XmlWriterSettings"/></param>
/// <returns>A XML string that represents the object to be serialized</returns>
public static string Serialize(T source, XmlSerializerNamespaces namespaces, XmlWriterSettings settings)
{
if (source == null)
throw new ArgumentNullException("source", "Object to serialize cannot be null");
string xml = null;
XmlSerializer serializer = new XmlSerializer(source.GetType());
using (MemoryStream memoryStream = new MemoryStream())
{
using (XmlWriter xmlWriter = XmlWriter.Create(memoryStream, settings))
{
System.Xml.Serialization.XmlSerializer x = new System.Xml.Serialization.XmlSerializer(typeof(T));
x.Serialize(xmlWriter, source, namespaces);
memoryStream.Position = 0; // rewind the stream before reading back.
using (StreamReader sr = new StreamReader(memoryStream))
{
xml = sr.ReadToEnd();
}
}
}
return xml;
}
/// <summary>
/// Serialize an object to a XML file
/// </summary>
/// <param name="source">The object to serialize</param>
/// <param name="filename">The file to generate</param>
public static void SerializeToFile(T source, string filename)
{
// indented XML by default
SerializeToFile(source, filename, null, GetIndentedSettings());
}
/// <summary>
/// Serialize an object to a XML file
/// </summary>
/// <param name="source">The object to serialize</param>
/// <param name="filename">The file to generate</param>
/// <param name="namespaces">Namespaces to include in serialization</param>
public static void SerializeToFile(T source, string filename, XmlSerializerNamespaces namespaces)
{
// indented XML by default
SerializeToFile(source, filename, namespaces, GetIndentedSettings());
}
/// <summary>
/// Serialize an object to a XML file
/// </summary>
/// <param name="source">The object to serialize</param>
/// <param name="filename">The file to generate</param>
/// <param name="settings">XML serialization settings. <see cref="System.Xml.XmlWriterSettings"/></param>
public static void SerializeToFile(T source, string filename, XmlWriterSettings settings)
{
SerializeToFile(source, filename, null, settings);
}
/// <summary>
/// Serialize an object to a XML file
/// </summary>
/// <param name="source">The object to serialize</param>
/// <param name="filename">The file to generate</param>
/// <param name="namespaces">Namespaces to include in serialization</param>
/// <param name="settings">XML serialization settings. <see cref="System.Xml.XmlWriterSettings"/></param>
public static void SerializeToFile(T source, string filename, XmlSerializerNamespaces namespaces, XmlWriterSettings settings)
{
if (source == null)
throw new ArgumentNullException("source", "Object to serialize cannot be null");
XmlSerializer serializer = new XmlSerializer(source.GetType());
using (XmlWriter xmlWriter = XmlWriter.Create(filename, settings))
{
System.Xml.Serialization.XmlSerializer x = new System.Xml.Serialization.XmlSerializer(typeof(T));
x.Serialize(xmlWriter, source, namespaces);
}
}
#region Private methods
private static XmlWriterSettings GetIndentedSettings()
{
XmlWriterSettings xmlWriterSettings = new XmlWriterSettings();
xmlWriterSettings.Indent = true;
xmlWriterSettings.IndentChars = "\t";
return xmlWriterSettings;
}
#endregion
}
I found my solution. No the best, but it is working.
I impleted IXmlSerializable and handeled the stuff by myself:
public void ReadXml(System.Xml.XmlReader reader)
{
reader.Read();
reader.MoveToContent();
if (reader.LocalName == "AnotherNode")
{
var innerXml = Serializer<AnotherClass>.CreateSerializer();
Remove = (AnotherClass) innerXml.Deserialize(reader);
reader.MoveToContent();
}
reader.Read();
// Here is the trick
if (reader.IsStartElement())
{
do
{
var innerXml = Serializer<T>.CreateSerializer();
var obj = (T) innerXml.Deserialize(reader);
Updates.Add(obj);
} while (reader.MoveToContent() == XmlNodeType.Element);
}
}
public void WriteXml(System.Xml.XmlWriter writer)
{
var removeSerializer = Serializer<RemoveElement>.CreateSerializer();
removeSerializer.Serialize(writer, Remove);
if (Updates.Any())
{
var innerXml = Serializer<T>.CreateSerializer();
writer.WriteStartElement("ContentUpdates");
foreach (var update in Updates)
{
innerXml.Serialize(writer, update);
}
writer.WriteEndElement();
}
}
Consider using DataContractSerializer instead of XmlSerializer.
XmlSerializer is generating at runtime a temp assembly, in order to speed up
serialization - deserialization process later on. Thus it requires code compilation.
DataContractSerializer on the other hand does not. In case you use the DataContractSerializer
approach you have to play around with appropriate attributes, so that you control "inheritence"
issues.
That sounds like a bug in the code-emitter for XmlSerializer for the Windows Store platform specifically, but it is a bit moot, because it still fails on regular .NET, but with a different message:
Unable to generate a temporary class (result=1).
error CS0030: Cannot convert type 'News' to 'Event'
error CS1502: The best overloaded method match for 'System.Collections.Generic.List.Add(News)' has some invalid arguments
error CS1503: Argument 1: cannot convert from 'Event' to 'News'
So basically, it looks like an unsupported scenario that manifests differently in the two scenarios. Fundamentally, the issue is that you're annotations are saying (for T=News) "if this News is a News, call the element 'NewsObject'; if this News is an Event, call the element 'EventObject'" - which is odd because a News is never an Event, etc.
However, the good news is that what you want to do can be done just using [XmlType(...)]:
[XmlType("NewsObject")]
public class News : BaseContent
{
// Some more auto properties
public int B { get; set; }
}
[XmlType("EventObject")]
public class Event : BaseContent
{
// Some more auto properites
public int C { get; set; }
}
...
public class GenericResponse<T>
{
[XmlArray("Content")]
public List<T> ContentItems { get; set; }
}
note: no [XmlArrayItem(...)] in the above.
which then outputs (after formatting, cleaning, etc):
<NewsResponse>
<Content>
<NewsObject><A>1</A><B>2</B></NewsObject>
</Content>
</NewsResponse>
via the test code:
var obj = new NewsResponse { ContentItems = new List<News> {
new News { A = 1, B = 2 } } };
var sw = new StringWriter();
using (var xw = System.Xml.XmlWriter.Create(sw))
{
var ser = new XmlSerializer(obj.GetType());
ser.Serialize(xw, obj);
}
string xml = sw.ToString();
If you need more control than that, then XmlAttributeOverrides is the thing to look at; but you must cache serializers created with XmlAttributeOverrides, to avoid hemorrhaging assemblies and getting a memory leak.
I have a C# class that I have inherited. I have successfully "built" the object. But I need to serialize the object to XML. Is there an easy way to do it?
It looks like the class has been set up for serialization, but I'm not sure how to get the XML representation. My class definition looks like this:
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.1")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://www.domain.com/test")]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "http://www.domain.com/test", IsNullable = false)]
public partial class MyObject
{
...
}
Here is what I thought I could do, but it doesn't work:
MyObject o = new MyObject();
// Set o properties
string xml = o.ToString();
How do I get the XML representation of this object?
You have to use XmlSerializer for XML serialization. Below is a sample snippet.
XmlSerializer xsSubmit = new XmlSerializer(typeof(MyObject));
var subReq = new MyObject();
var xml = "";
using(var sww = new StringWriter())
{
using(XmlWriter writer = XmlWriter.Create(sww))
{
xsSubmit.Serialize(writer, subReq);
xml = sww.ToString(); // Your XML
}
}
As per #kiquenet request for generic class:
public class MySerializer<T> where T : class
{
public static string Serialize(T obj)
{
XmlSerializer xsSubmit = new XmlSerializer(typeof(T));
using (var sww = new StringWriter())
{
using (XmlTextWriter writer = new XmlTextWriter(sww) { Formatting = Formatting.Indented })
{
xsSubmit.Serialize(writer, obj);
return sww.ToString();
}
}
}
}
usage:
string xmlMessage = MySerializer<MyClass>.Serialize(myObj);
I modified mine to return a string rather than use a ref variable like below.
public static string Serialize<T>(this T value)
{
if (value == null)
{
return string.Empty;
}
try
{
var xmlserializer = new XmlSerializer(typeof(T));
var stringWriter = new StringWriter();
using (var writer = XmlWriter.Create(stringWriter))
{
xmlserializer.Serialize(writer, value);
return stringWriter.ToString();
}
}
catch (Exception ex)
{
throw new Exception("An error occurred", ex);
}
}
Its usage would be like this:
var xmlString = obj.Serialize();
The following function can be copied to any object to add an XML save function using the System.Xml namespace.
/// <summary>
/// Saves to an xml file
/// </summary>
/// <param name="FileName">File path of the new xml file</param>
public void Save(string FileName)
{
using (var writer = new System.IO.StreamWriter(FileName))
{
var serializer = new XmlSerializer(this.GetType());
serializer.Serialize(writer, this);
writer.Flush();
}
}
To create the object from the saved file, add the following function and replace [ObjectType] with the object type to be created.
/// <summary>
/// Load an object from an xml file
/// </summary>
/// <param name="FileName">Xml file name</param>
/// <returns>The object created from the xml file</returns>
public static [ObjectType] Load(string FileName)
{
using (var stream = System.IO.File.OpenRead(FileName))
{
var serializer = new XmlSerializer(typeof([ObjectType]));
return serializer.Deserialize(stream) as [ObjectType];
}
}
Extension class:
using System.IO;
using System.Xml;
using System.Xml.Serialization;
namespace MyProj.Extensions
{
public static class XmlExtension
{
public static string Serialize<T>(this T value)
{
if (value == null) return string.Empty;
var xmlSerializer = new XmlSerializer(typeof(T));
using (var stringWriter = new StringWriter())
{
using (var xmlWriter = XmlWriter.Create(stringWriter,new XmlWriterSettings{Indent = true}))
{
xmlSerializer.Serialize(xmlWriter, value);
return stringWriter.ToString();
}
}
}
}
}
Usage:
Foo foo = new Foo{MyProperty="I have been serialized"};
string xml = foo.Serialize();
Just reference the namespace holding your extension method in the file you would like to use it in and it'll work (in my example it would be: using MyProj.Extensions;)
Note that if you want to make the extension method specific to only a particular class(eg., Foo), you can replace the T argument in the extension method, eg.
public static string Serialize(this Foo value){...}
You can use the function like below to get serialized XML from any object.
public static bool Serialize<T>(T value, ref string serializeXml)
{
if (value == null)
{
return false;
}
try
{
XmlSerializer xmlserializer = new XmlSerializer(typeof(T));
StringWriter stringWriter = new StringWriter();
XmlWriter writer = XmlWriter.Create(stringWriter);
xmlserializer.Serialize(writer, value);
serializeXml = stringWriter.ToString();
writer.Close();
return true;
}
catch (Exception ex)
{
return false;
}
}
You can call this from the client.
All upvoted answers above are correct. This is just simplest version:
private string Serialize(Object o)
{
using (var writer = new StringWriter())
{
new XmlSerializer(o.GetType()).Serialize(writer, o);
return writer.ToString();
}
}
To serialize an object, do:
using (StreamWriter myWriter = new StreamWriter(path, false))
{
XmlSerializer mySerializer = new XmlSerializer(typeof(your_object_type));
mySerializer.Serialize(myWriter, objectToSerialize);
}
Also remember that for XmlSerializer to work, you need a parameterless constructor.
I will start with the copy answer of Ben Gripka:
public void Save(string FileName)
{
using (var writer = new System.IO.StreamWriter(FileName))
{
var serializer = new XmlSerializer(this.GetType());
serializer.Serialize(writer, this);
writer.Flush();
}
}
I used this code earlier. But reality showed that this solution is a bit problematic. Usually most of programmers just serialize setting on save and deserialize settings on load. This is an optimistic scenario. Once the serialization failed, because of some reason, the file is partly written, XML file is not complete and it is invalid. In consequence XML deserialization does not work and your application may crash on start. If the file is not huge, I suggest first serialize object to MemoryStream then write the stream to the File. This case is especially important if there is some complicated custom serialization. You can never test all cases.
public void Save(string fileName)
{
//first serialize the object to memory stream,
//in case of exception, the original file is not corrupted
using (MemoryStream ms = new MemoryStream())
{
var writer = new System.IO.StreamWriter(ms);
var serializer = new XmlSerializer(this.GetType());
serializer.Serialize(writer, this);
writer.Flush();
//if the serialization succeed, rewrite the file.
File.WriteAllBytes(fileName, ms.ToArray());
}
}
The deserialization in real world scenario should count with corrupted serialization file, it happens sometime. Load function provided by Ben Gripka is fine.
public static [ObjectType] Load(string fileName)
{
using (var stream = System.IO.File.OpenRead(fileName))
{
var serializer = new XmlSerializer(typeof([ObjectType]));
return serializer.Deserialize(stream) as [ObjectType];
}
}
And it could be wrapped by some recovery scenario. It is suitable for settings files or other files which can be deleted in case of problems.
public static [ObjectType] LoadWithRecovery(string fileName)
{
try
{
return Load(fileName);
}
catch(Excetion)
{
File.Delete(fileName); //delete corrupted settings file
return GetFactorySettings();
}
}
It's a little bit more complicated than calling the ToString method of the class, but not much.
Here's a simple drop-in function you can use to serialize any type of object. It returns a string containing the serialized XML contents:
public string SerializeObject(object obj)
{
System.Xml.XmlDocument xmlDoc = new System.Xml.XmlDocument();
System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(obj.GetType());
using (System.IO.MemoryStream ms = new System.IO.MemoryStream()) {
serializer.Serialize(ms, obj);
ms.Position = 0;
xmlDoc.Load(ms);
return xmlDoc.InnerXml;
}
}
Based on above solutions, here comes a extension class which you can use to serialize and deserialize any object. Any other XML attributions are up to you.
Just use it like this:
string s = new MyObject().Serialize(); // to serialize into a string
MyObject b = s.Deserialize<MyObject>();// deserialize from a string
internal static class Extensions
{
public static T Deserialize<T>(this string value)
{
var xmlSerializer = new XmlSerializer(typeof(T));
return (T)xmlSerializer.Deserialize(new StringReader(value));
}
public static string Serialize<T>(this T value)
{
if (value == null)
return string.Empty;
var xmlSerializer = new XmlSerializer(typeof(T));
using (var stringWriter = new StringWriter())
{
using (var xmlWriter = XmlWriter.Create(stringWriter, new XmlWriterSettings { Indent = true }))
{
xmlSerializer.Serialize(xmlWriter, value);
return stringWriter.ToString();
}
}
}
}
I have a simple way to serialize an object to XML using C#, it works great and it's highly reusable. I know this is an older thread, but I wanted to post this because someone may find this helpful to them.
Here is how I call the method:
var objectToSerialize = new MyObject();
var xmlString = objectToSerialize.ToXmlString();
Here is the class that does the work:
Note: Since these are extension methods they need to be in a static class.
using System.IO;
using System.Xml.Serialization;
public static class XmlTools
{
public static string ToXmlString<T>(this T input)
{
using (var writer = new StringWriter())
{
input.ToXml(writer);
return writer.ToString();
}
}
private static void ToXml<T>(this T objectToSerialize, StringWriter writer)
{
new XmlSerializer(typeof(T)).Serialize(writer, objectToSerialize);
}
}
Here is a good tutorial on how to do this
You should basically use System.Xml.Serialization.XmlSerializer class to do this.
my work code. Returns utf8 xml enable empty namespace.
// override StringWriter
public class Utf8StringWriter : StringWriter
{
public override Encoding Encoding => Encoding.UTF8;
}
private string GenerateXmlResponse(Object obj)
{
Type t = obj.GetType();
var xml = "";
using (StringWriter sww = new Utf8StringWriter())
{
using (XmlWriter writer = XmlWriter.Create(sww))
{
var ns = new XmlSerializerNamespaces();
// add empty namespace
ns.Add("", "");
XmlSerializer xsSubmit = new XmlSerializer(t);
xsSubmit.Serialize(writer, obj, ns);
xml = sww.ToString(); // Your XML
}
}
return xml;
}
Example returns response Yandex api payment Aviso url:
<?xml version="1.0" encoding="utf-8"?><paymentAvisoResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" performedDatetime="2017-09-01T16:22:08.9747654+07:00" code="0" shopId="54321" invoiceId="12345" orderSumAmount="10643" />
string FilePath = ConfigurationReader.FileLocation; //Getting path value from web.config
XmlSerializer serializer = new XmlSerializer(typeof(Devices)); //typeof(object)
MemoryStream memStream = new MemoryStream();
serializer.Serialize(memStream, lstDevices);//lstdevices : I take result as a list.
FileStream file = new FileStream(folderName + "\\Data.xml", FileMode.Create, FileAccess.ReadWrite); //foldername:Specify the path to store the xml file
memStream.WriteTo(file);
file.Close();
You can create and store the result as xml file in the desired location.
Or you can add this method to your object:
public void Save(string filename)
{
var ser = new XmlSerializer(this.GetType());
using (var stream = new FileStream(filename, FileMode.Create))
ser.Serialize(stream, this);
}
Here's a basic code that will help serializing the C# objects into xml:
using System;
public class clsPerson
{
public string FirstName;
public string MI;
public string LastName;
}
class class1
{
static void Main(string[] args)
{
clsPerson p=new clsPerson();
p.FirstName = "Jeff";
p.MI = "A";
p.LastName = "Price";
System.Xml.Serialization.XmlSerializer x = new System.Xml.Serialization.XmlSerializer(p.GetType());
x.Serialize(Console.Out, p);
Console.WriteLine();
Console.ReadLine();
}
}
public string ObjectToXML(object input)
{
try
{
var stringwriter = new System.IO.StringWriter();
var serializer = new XmlSerializer(input.GetType());
serializer.Serialize(stringwriter, input);
return stringwriter.ToString();
}
catch (Exception ex)
{
if (ex.InnerException != null)
ex = ex.InnerException;
return "Could not convert: " + ex.Message;
}
}
//Usage
var res = ObjectToXML(obj)
You need to use following classes:
using System.IO;
using System.Xml;
using System.Xml.Serialization;
Here is a generic object serializer:
using System.IO;
using System.Text;
using System.Xml.Schema;
namespace System.Xml.Serialization
{
/// <summary>
/// Serializes and deserializes <typeparamref name="T"/> objects into XML documents.
/// Allows you to control the process of encoding objects in XML.
/// </summary>
/// <typeparam name="T">Object type.</typeparam>
public static class XmlSerializer<T>
{
private static readonly XmlSerializer _serializer = new XmlSerializer(typeof(T));
private static readonly XmlWriterSettings _defaultWriterSettings = new XmlWriterSettings
{
CheckCharacters = false
CloseOutput=false
ConformanceLevel = ConformanceLevel.Auto,
Encoding = Encoding.UTF8,
indent=true,
IndentChars = "\t",
NamespaceHandling = NamespaceHandling.OmitDuplicates,
NewLineChars = "\r\n",
NewLineHandling = NewLineHandling.Replace,
NewLineOnAttributes = false,
OmitXmlDeclaration = false
};
private static readonly XmlReaderSettings _defaultReaderSettings = new XmlReaderSettings
{
CheckCharacters = false
CloseInput=false
ConformanceLevel = ConformanceLevel.Auto,
DtdProcessing = DtdProcessing.Prohibit,
IgnoreComments = true,
IgnoreProcessingInstructions = true,
IgnoreWhitespace=true,
LineNumberOffset = 0
LinePositionOffset = 0
MaxCharactersFromEntities = 0,
MaxCharactersInDocument = 0,
NameTable = null
// Schemas = null, // ???
ValidationFlags = XmlSchemaValidationFlags.None,
ValidationType = ValidationType. None,
XmlResolver = null
};
/// <summary>
/// Default character encoding.
/// </summary>
public static Encoding DefaultEncoding => Encoding.UTF8;
/// <summary>
/// Default settings for the <see cref="XmlWriter" /> instance being created.
/// </summary>
public static XmlWriterSettings DefaultXmlWriterSettings => _defaultWriterSettings.Clone();
/// <summary>
/// Default settings for the <see cref="XmlReader" /> instance that is created.
/// </summary>
public static XmlReaderSettings DefaultXmlReaderSettings => _defaultReaderSettings.Clone();
/// <summary>
/// Serializes the given <typeparamref name="T"/> and returns the XML document as a string.
/// </summary>
/// <param name="o">
/// Instance <see cref="object" /> to serialize.
/// </param>
public static string Serialize(T o)
{
StringBuilder sb = new StringBuilder();
using (XmlWriter xmlWriter = XmlWriter.Create(sb))
_serializer.Serialize(xmlWriter, o, (XmlSerializerNamespaces)null);
return sb.ToString();
}
/// <summary>
/// Serializes the given <typeparamref name="T"/> and returns the XML document as a string.
/// </summary>
/// <param name="o">
/// Instance <see cref="object" /> to serialize.
/// </param>
/// <param name="settings">
/// Settings for the new <see cref="XmlWriter" /> instance. If <see langword="null"/> is specified,
/// settings are used <see cref="DefaultXmlWriterSettings"/>.
/// </param>
public static string Serialize(T o, XmlWriterSettings settings)
{
if (settings == null) settings = _defaultWriterSettings;
StringBuilder sb = new StringBuilder();
using (XmlWriter xmlWriter = XmlWriter.Create(sb, settings))
_serializer.Serialize(xmlWriter, o, (XmlSerializerNamespaces)null);
return sb.ToString();
}
/// <summary>
/// Serializes the given <typeparamref name="T"/> and writes the XML document to a file using the given <see cref="TextWriter" />.
/// </summary>
/// <param name="textWriter">
/// <see cref="TextWriter" /> Used to write an XML document.
/// </param>
/// <param name="o">
/// Instance <see cref="object" /> to serialize.
/// </param>
public static void Serialize(TextWriter textWriter, T o)
{
using (XmlWriter xmlWriter = XmlWriter.Create(textWriter))
_serializer.Serialize(textWriter, o, (XmlSerializerNamespaces)null);
}
/// <summary>
/// Serializes the given <typeparamref name="T"/> and writes the XML document to a file using the given <see cref="TextWriter" />.
/// </summary>
/// <param name="textWriter">
/// <see cref="TextWriter" /> Used to write an XML document.
/// </param>
/// <param name="o">
/// Instance <see cref="object" /> to serialize.
/// </param>
/// <param name="settings">
/// Settings for the new <see cref="XmlWriter" /> instance. If <see langword="null"/> is specified,
/// settings are used <see cref="DefaultXmlWriterSettings"/>.
/// </param>
public static void Serialize(TextWriter textWriter, T o, XmlWriterSettings settings)
{
if (settings == null) settings = _defaultWriterSettings;
using (XmlWriter xmlWriter = XmlWriter.Create(textWriter, settings))
_serializer.Serialize(xmlWriter, o, (XmlSerializerNamespaces)null);
}
/// <summary>
/// Serializes the given <typeparamref name="T"/> and writes the XML document to a file using the given <see cref="TextWriter" /> and references to the given namespaces.
/// </summary>
/// <param name="textWriter">
/// <see cref="TextWriter" /> Used to write an XML document.
/// </param>
/// <param name="o">
/// Instance <see cref="object" /> to serialize.
/// </param>
/// <param name="namespaces">
/// <see cref="XmlSerializerNamespaces" /> Contains the namespaces for the generated XML document.
/// </param>
/// <exception cref="InvalidOperationException">
/// An error occurred during serialization.
/// The original exception is accessible using the <see cref="P:System.Exception.InnerException" /> property.
/// </exception>
public static void Serialize(TextWriter textWriter, T o, XmlSerializerNamespaces namespaces)
{
using (XmlWriter xmlWriter = XmlWriter.Create(textWriter))
_serializer.Serialize(xmlWriter, o, namespaces);
}
/// <summary>
/// Serializes the given <typeparamref name="T"/> and writes the XML document to a file using the given <see cref="TextWriter" /> and references to the given namespaces.
/// </summary>
/// <param name="textWriter">
/// <see cref="TextWriter" /> Used to write an XML document.
/// </param>
/// <param name="o">
/// Instance <see cref="object" /> to serialize.
/// </param>
/// <param name="namespaces">
/// <see cref="XmlSerializerNamespaces" /> Contains the namespaces for the generated XML document.
/// </param>
/// <param name="settings">
/// Settings for the new <see cref="XmlWriter" /> instance. If <see langword="null"/> is specified,
/// settings are used <see cref="DefaultXmlWriterSettings"/>.
/// </param>
/// <exception cref="InvalidOperationException">
/// An error occurred during serialization.
/// The original exception is accessible using the <see cref="P:System.Exception.InnerException" /> property.
/// </exception>
public static void Serialize(TextWriter textWriter, T o, XmlSerializerNamespaces namespaces, XmlWriterSettings settings)
{
if (settings == null) settings = _defaultWriterSettings;
using (XmlWriter xmlWriter = XmlWriter.Create(textWriter, settings))
_serializer.Serialize(xmlWriter, o, namespaces);
}
/// <summary>
/// Serializes the given <typeparamref name="T"/> and writes the XML document to a file using the given <see cref="Stream" />.
/// </summary>
/// <param name="stream">
/// <see cref="Stream" /> Used to write an XML document.
/// </param>
/// <param name="o">
/// Instance <see cref="object" /> to serialize.
/// </param>
/// <exception cref="InvalidOperationException">
/// An error occurred during serialization.
/// The original exception is accessible using the <see cref="P:System.Exception.InnerException" /> property.
/// </exception>
public static void Serialize(Stream stream, T o)
{
_serializer.Serialize(stream, o, (XmlSerializerNamespaces)null);
}
/// <summary>
/// Serializes the given <typeparamref name="T"/> and writes the XML document to a file using the given <see cref="Stream" />.
/// </summary>
/// <param name="stream">
/// <see cref="Stream" /> Used to write an XML document.
/// </param>
/// <param name="o">
/// Instance <see cref="object" /> to serialize.
/// </param>
/// <param name="settings">
/// Settings for the new <see cref="XmlWriter" /> instance. If <see langword="null"/> is specified,
/// settings are used <see cref="DefaultXmlWriterSettings"/>.
/// </param>
/// <exception cref="InvalidOperationException">
/// An error occurred during serialization.
/// The original exception is accessible using the <see cref="P:System.Exception.InnerException" /> property.
/// </exception>
public static void Serialize(Stream stream, T o, XmlWriterSettings settings)
{
if (settings == null) settings = _defaultWriterSettings;
using (TextWriter writer = new StreamWriter(stream, settings.Encoding))
using (XmlWriter xmlWriter = XmlWriter.Create(writer, settings))
_serializer.Serialize(xmlWriter, o, (XmlSerializerNamespaces) null);
}
/// <summary>
/// Serializes the given <typeparamref name="T"/> and writes the XML document to a file using the given <see cref="Stream" /> refers to the given namespaces.
/// </summary>
/// <param name="stream">
/// <see cref="Stream" /> Used to write an XML document.
/// </param>
/// <param name="o">
/// Instance <see cref="object" /> to serialize.
/// </param>
/// <param name="namespaces">
/// <see cref="XmlSerializerNamespaces" /> The object is referenced.
/// </param>
/// <exception cref="InvalidOperationException">
/// An error occurred during serialization.
/// The original exception is accessible using the <see cref="P:System.Exception.InnerException" /> property.
/// </exception>
public static void Serialize(Stream stream, T o, XmlSerializerNamespaces namespaces)
{
_serializer.Serialize(stream, o, namespaces);
}
/// <summary>
/// Serializes the given <typeparamref name="T"/> and writes the XML document to a file using the given <see cref="Stream" /> refers to the given namespaces.
/// </summary>
/// <param name="stream">
/// <see cref="Stream" /> Used to write an XML document.
/// </param>
/// <param name="o">
/// Instance <see cref="object" /> to serialize.
/// </param>
/// <param name="namespaces">
/// <see cref="XmlSerializerNamespaces" /> The object is referenced.
/// </param>
/// <param name="settings">
/// Settings for the new <see cref="XmlWriter" /> instance. If <see langword="null"/> is specified,
/// settings are used <see cref="DefaultXmlWriterSettings"/>.
/// </param>
/// <exception cref="InvalidOperationException">
/// An error occurred during serialization.
/// The original exception is accessible using the <see cref="P:System.Exception.InnerException" /> property.
/// </exception>
public static void Serialize(Stream stream, T o, XmlSerializerNamespaces namespaces, XmlWriterSettings settings)
{
if (settings == null) settings = _defaultWriterSettings;
using (TextWriter writer = new StreamWriter(stream, settings.Encoding))
using (XmlWriter xmlWriter = XmlWriter.Create(writer, settings))
_serializer.Serialize(xmlWriter, o, namespaces);
}
/// <summary>
/// Serializes the given <typeparamref name="T"/> and writes the XML document to a file using the given <see cref="XmlWriter" />.
/// </summary>
/// <param name="xmlWriter">
/// <see cref="XmlWriter" /> Used to write an XML document.
/// </param>
/// <param name="o">
/// Instance <see cref="object" /> to serialize.
/// </param>
/// <param name="settings">
/// Settings for the new <see cref="XmlWriter" /> instance. If <see langword="null"/> is specified,
/// the settings of the current <see cref="XmlWriter" /> instance are used.
/// </param>
/// <exception cref="InvalidOperationException">
/// An error occurred during serialization.
/// The original exception is accessible using the <see cref="P:System.Exception.InnerException" /> property.
/// </exception>
public static void Serialize(XmlWriter xmlWriter, T o, XmlWriterSettings settings = null)
{
using (XmlWriter writer = settings == null ? xmlWriter : XmlWriter.Create(xmlWriter, settings))
_serializer.Serialize(writer, o, (XmlSerializerNamespaces)null);
}
/// <summary>
/// Serializes the given <typeparamref name="T"/> and writes the XML document to a file using the given <see cref="XmlWriter" /> and references to the given namespaces.
/// </summary>
/// <param name="xmlWriter">
/// <see cref="XmlWriter" /> Used to write an XML document.
/// </param>
/// <param name="o">
/// Instance <see cref="object" /> to serialize.
/// </param>
/// <param name="namespaces">
/// <see cref="XmlSerializerNamespaces" /> The object is referenced.
/// </param>
/// <param name="settings">
/// Settings for the new <see cref="XmlWriter" /> instance. If <see langword="null"/> is specified,
/// the settings of the current <see cref="XmlWriter" /> instance are used.
/// </param>
/// <exception cref="InvalidOperationException">
/// An error occurred during serialization.
/// The original exception is accessible using the <see cref="P:System.Exception.InnerException" /> property.
/// </exception>
public static void Serialize(XmlWriter xmlWriter, T o, XmlSerializerNamespaces namespaces, XmlWriterSettings settings = null)
{
using (XmlWriter writer = settings == null ? xmlWriter : XmlWriter.Create(xmlWriter, settings))
_serializer.Serialize(writer, o, namespaces);
}
/// <summary>
/// Serializes the specified object and writes the XML document to a file using the specified <typeparamref name="T"/> and references the specified namespaces and encoding style.
/// </summary>
/// <param name="xmlWriter">
/// <see cref="XmlWriter" /> Used to write an XML document.
/// </param>
/// <param name="o">Object to serialize.</param>
/// <param name="namespaces">
/// <see cref="XmlSerializerNamespaces" /> The object is referenced.
/// </param>
/// <param name="encodingStyle">
/// The encoding style of the serialized XML.
/// </param>
/// <param name="settings">
/// Settings for the new <see cref="XmlWriter" /> instance. If <see langword="null"/> is specified,
/// the settings of the current <see cref="XmlWriter" /> instance are used.
/// </param>
/// <exception cref="InvalidOperationException">
/// An error occurred during serialization.
/// The original exception is accessible using the <see cref="P:System.Exception.InnerException" /> property.
/// </exception>
public static void Serialize(
XmlWriter xmlWriter,
T o
XmlSerializerNamespaces,
string encodingStyle,
XmlWriterSettings settings = null)
{
using (XmlWriter writer = settings == null ? xmlWriter : XmlWriter.Create(xmlWriter, settings))
_serializer.Serialize(writer, o, namespaces, encodingStyle, (string)null);
}
/// <summary>
/// Serializes the given <typeparamref name="T"/> and writes the XML document to a file using the given <see cref="XmlWriter" />, XML namespaces, and encoding.
/// </summary>
/// <param name="xmlWriter">
/// <see cref="XmlWriter" /> Used to write an XML document.
/// </param>
/// <param name="o">Object to serialize.</param>
/// <param name="namespaces">
/// An instance of <see langword="XmlSerializaerNamespaces" /> containing the namespaces and prefixes used.
/// </param>
/// <param name="encodingStyle">
/// The encoding used in the document.
/// </param>
/// <param name="id">
/// For SOAP encoded messages, a base is used to generate identifier attributes.
/// </param>
/// <param name="settings">
/// Settings for the new <see cref="XmlWriter" /> instance. If <see langword="null"/> is specified,
/// the settings of the current <see cref="XmlWriter" /> instance are used.
/// </param>
public static void Serialize(
XmlWriter xmlWriter,
T o
XmlSerializerNamespaces,
string encodingStyle,
string id,
XmlWriterSettings settings = null)
{
using (XmlWriter writer = settings == null ? xmlWriter : XmlWriter.Create(xmlWriter, settings))
_serializer.Serialize(writer, o, namespaces, encodingStyle, id);
}
/// <summary>
/// Deserializes the XML document contained in the specified string.
/// </summary>
/// settings are used <see cref="DefaultXmlReaderSettings"/>.</param>
/// <returns> The deserialized object <typeparamref name="T"/>. </returns>
public static T Deserialize(string text)
{
using (StringReader reader = new StringReader(text))
using (XmlReader xmlReader = XmlReader.Create(reader))
return (T)_serializer.Deserialize(xmlReader);
}
/// <summary>
/// Deserializes the XML document contained in the specified string.
/// </summary>
/// <param name="text">String containing the XML document.</param>
/// <param name="settings"> Settings for the new <see cref="XmlReader" /> instance. If <see langword="null"/> is specified,
/// settings are used <see cref="DefaultXmlReaderSettings"/>.</param>
/// <returns> The deserialized object <typeparamref name="T"/>. </returns>
public static T Deserialize(string text, XmlReaderSettings settings)
{
if (settings == null) settings = _defaultReaderSettings;
using (StringReader reader = new StringReader(text))
using (XmlReader xmlReader = XmlReader.Create(reader, settings))
return (T)_serializer.Deserialize(xmlReader);
}
/// <summary>
/// Deserializes the XML document contained in the specified <see cref="Stream" />.
/// </summary>
/// <param name="stream">
/// <see cref="Stream" /> Containing the XML document to deserialize.
/// </param>
/// <returns>
/// Deserialized object <typeparamref name="T"/>.
/// </returns>
public static T Deserialize(Stream stream)
{
return (T)_serializer.Deserialize(stream);
}
/// <summary>
/// Deserializes the XML document contained in the specified <see cref="Stream" />.
/// </summary>
/// <param name="stream">
/// <see cref="Stream" /> Containing the XML document to deserialize.
/// </param>
/// <param name="settings">Settings for the new <see cref="XmlReader" /> instance. If <see langword="null"/> is specified,
/// settings are used <see cref="DefaultXmlReaderSettings"/>.</param>
/// <returns>
/// Deserialized object <typeparamref name="T"/>.
/// </returns>
public static T Deserialize(Stream stream, XmlReaderSettings settings)
{
if (settings == null) settings = _defaultReaderSettings;
using(XmlReader xmlReader = XmlReader.Create(stream, settings))
return (T)_serializer.Deserialize(xmlReader);
}
/// <summary>
/// Deserializes the XML document contained in the specified <see cref="TextReader" />.
/// </summary>
/// <param name="textReader">
/// <see cref="TextReader" /> The containing XML document to deserialize.
/// </param>
/// <returns>
/// Deserialized object <typeparamref name="T"/>.
/// </returns>
/// <exception cref="InvalidOperationException">
/// An error occurred during deserialization.
/// The original exception is accessible using the <see cref="P:System.Exception.InnerException" /> property.
/// </exception>
public static T Deserialize(TextReader textReader)
{
return (T) _serializer.Deserialize(textReader);
}
/// <summary>
/// Deserializes the XML document contained in the specified <see cref="TextReader" />.
/// </summary>
/// <param name="textReader">
/// <see cref="TextReader" /> The containing XML document to deserialize.
/// </param>
/// <param name="settings">Settings for the new <see cref="XmlReader" /> instance. If <see langword="null"/> is specified,
/// settings are used <see cref="DefaultXmlReaderSettings"/>.</param>
/// <returns>
/// Deserialized object <typeparamref name="T"/>.
/// </returns>
/// <exception cref="InvalidOperationException">
/// An error occurred during deserialization.
/// The original exception is accessible using the <see cref="P:System.Exception.InnerException" /> property.
/// </exception>
public static T Deserialize(TextReader textReader, XmlReaderSettings settings)
{
if (settings == null) settings = _defaultReaderSettings;
using (XmlReader xmlReader = XmlReader.Create(textReader, settings))
return (T)_serializer.Deserialize(xmlReader);
}
/// <summary>
/// Deserializes the XML document contained in the specified <see cref="XmlReader" />.
/// </summary>
/// <param name="xmlReader">
/// <see cref="XmlReader" /> The containing XML document to deserialize.
/// </param>
/// <param name="settings">Settings for the new <see cref="XmlReader" /> instance. If <see langword="null"/> is specified,
/// current instance settings are used <see cref="XmlReader" />.</param>
/// <returns>
/// Deserialized object <typeparamref name="T"/>.
/// </returns>
/// <exception cref="InvalidOperationException">
/// An error occurred during deserialization.
/// The original exception is accessible using the <see cref="P:System.Exception.InnerException" /> property.
/// </exception>
public static T Deserialize(XmlReader xmlReader, XmlReaderSettings settings = null)
{
using (XmlReader reader = settings == null ? xmlReader : XmlReader.Create(xmlReader, settings))
return (T)_serializer.Deserialize(xmlReader);
}
/// <summary>
/// Deserializes the XML document contained in the specified <see cref="XmlReader" /> and allows you to override events that occur during deserialization.
/// </summary>
/// <param name="xmlReader">
/// <see cref="XmlReader" /> The containing document to deserialize.
/// </param>
/// <param name="events">
/// Class instance <see cref="XmlDeserializationEvents" />.
/// </param>
/// <param name="settings">Settings for the new <see cref="XmlReader" /> instance. If <see langword="null"/> is specified,
/// current instance settings are used <see cref="XmlReader" />.</param>
/// <returns>
/// Deserialized object <typeparamref name="T"/>.
/// </returns>
public static T Deserialize(XmlReader xmlReader, XmlDeserializationEvents events, XmlReaderSettings settings = null)
{
using (XmlReader reader = settings == null ? xmlReader : XmlReader.Create(xmlReader, settings))
return (T)_serializer.Deserialize(reader, (string)null, events);
}
/// <summary>
/// Deserializes the XML document contained in the specified <see cref="XmlReader" /> and encoding style.
/// </summary>
/// <param name="xmlReader">
/// <see cref="XmlReader" /> The containing XML document to deserialize.
/// </param>
/// <param name="encodingStyle">
/// The encoding style of the serialized XML.
/// </param>
/// <param name="settings">Settings for the new <see cref="XmlReader" /> instance. If <see langword="null"/> is specified,
/// current instance settings are used <see cref="XmlReader" />.</param>
/// <returns>The deserialized object.</returns>
/// <exception cref="InvalidOperationException">
/// An error occurred during deserialization.
/// The original exception is accessible using the <see cref="P:System.Exception.InnerException" /> property.
/// </exception>
public static T Deserialize(XmlReader xmlReader, string encodingStyle, XmlReaderSettings settings = null)
{
using (XmlReader reader = settings == null ? xmlReader : XmlReader.Create(xmlReader, settings))
return (T)_serializer.Deserialize(reader, encodingStyle);
}
/// <summary>
/// Deserializes the object using the data contained in the specified <see cref="XmlReader" />.
/// </summary>
/// <param name="xmlReader">
/// An instance of the <see cref="XmlReader" /> class used to read the document.
/// </param>
/// <param name="encodingStyle">Encoding used.</param>
/// <param name="events">
/// Class instance <see cref="XmlDeserializationEvents" />.
/// </param>
/// <param name="settings">Settings for the new <see cref="XmlReader" /> instance. If <see langword="null"/> is specified,
/// current instance settings are used <see cref="XmlReader" />.</param>
/// <returns>The deserialized object <typeparamref name="T"/>.</returns>
public static object Deserialize(
xmlReader xmlReader,
string encodingStyle,
XmlDeserializationEvents events,
XmlReaderSettings settings = null)
{
using (XmlReader reader = settings == null ? xmlReader : XmlReader.Create(xmlReader, settings))
return _serializer.Deserialize(reader, encodingStyle, events);
}
/// <summary>
/// Returns a value indicating whether this <see cref="XmlSerializer" /> can deserialize the specified XML document.
/// </summary>
/// <param name="xmlReader">
/// <see cref="XmlReader" /> Pointing to the document to deserialize.
/// </param>
/// <returns>
/// <see langword="true" /> If this <see cref="XmlSerializer" /> can deserialize an object, <see cref="XmlReader" /> indicates; otherwise, <see langword="false" />.
/// </returns>
public static bool CanDeserialize(XmlReader xmlReader)
{
return _serializer.CanDeserialize(xmlReader);
}
}
}
It might be too late to party but there is serialization with only user defined Namespaces:
public static string XmlSerialize<T>(this T obj) where T : class
{
Type serialType = typeof(T);
var xsSubmit = new XmlSerializer(serialType);
XmlWriterSettings xws = new XmlWriterSettings() { OmitXmlDeclaration = true, Indent = true };
var Namespaces = new XmlSerializerNamespaces(new XmlQualifiedName[] {
new XmlQualifiedName(string.Empty, GetXmlNameSpace(serialType) ?? string.Empty )
});
private static string GetXmlNameSpace(Type target)
{
XmlRootAttribute attribute = (XmlRootAttribute)Attribute.GetCustomAttribute(target, typeof(XmlRootAttribute));
return attribute == null ? null : attribute.Namespace;
}
And defined namespace in the custom class
[XmlRoot("IdentityTerminal",Namespace = "http://my-name-space/XMLSchema")]
public class IdentityTerminal
{
}
This code allows to user only user defined namespaces and omit default ones.