I've got a requirement to pass parameters as Xml to my stored procedures.
I have a WCF service in the middle tier that makes calls to my data layer which in turn forwards the request to the appropriate stored procedure.
The design is that the WCF service is responsible for building the Xml to pass to the Repository.
I'm just wondering whether to keep control of what parameters are contained within the Xml in the middle tier or use a Dictionary built up by the client which I then convert to Xml in the middle tier?
At the moment I've gone for the latter - for example:
public TestQueryResponseMessage TestQuery(TestQueryRequestMessage message)
{
var result = Repository.ExecuteQuery("TestQuery", ParamsToXml(message.Body.Params));
return new TestQueryResponseMessage
{
Body = new TestQueryResponse
{
TopicItems = result;
}
}
}
private string ParamsToXml(Dictionary<string, string> nvc)
{
//TODO: Refactor
StringBuilder sb = new StringBuilder();
sb.Append("<params>");
foreach (KeyValuePair<string, string> param in nvc)
{
sb.Append("<param>");
sb.Append("<" + param.Key + ">");
sb.Append(param.Value);
sb.Append("</" + param.Key + ">");
sb.Append("</param>");
}
sb.Append("</params>");
return sb.ToString();
}
However I might need to do it the first way. E.g.
public TestQueryResponseMessage TestQuery(TestQueryRequestMessage message)
{
string xml = string.Format("<params><TestParameter>{0}</TestParameter></params>",message.Body.TestParameter)
var result = Repository.ExecuteQuery("TestQuery", xml);
return new TestQueryResponseMessage
{
Body = new TestQueryResponse
{
TopicItems = result;
}
}
}
What does the hivemind recommend?
If you must use xml; then rather than passing around a dictionary, I'd use a class that represents that data, and use XmlSerializer to fetch it as xml:
[Serializable, XmlRoot("args")]
public class SomeArgs {
[XmlElement("foo")] public string Foo { get; set; }
[XmlAttribute("bar")] public int Bar { get; set; }
}
...
SomeArgs args = new SomeArgs { Foo = "abc", Bar = 123 };
XmlSerializer ser = new XmlSerializer(typeof(SomeArgs));
StringWriter sw = new StringWriter();
ser.Serialize(sw, args);
string xml = sw.ToString();
This makes it much easier to manage which arguments apply to which queries, in an object-oriented way. It also means you don't have to do your own xml escaping...
Once you use Bob The Janitor's solution and you have your XML.
Create your stored procedure with a XML parameter. Then depending on how much XML you have and what your doing with it you can use Xquery or OpenXML to shred the XML document. Extract the data and perform the right action. This example is basic and pseudocode like but you should get the idea.
CREATE PROCEDURE [usp_Customer_INS_By_XML]
#Customer_XML XML
AS
BEGIN
EXEC sp_xml_preparedocument #xmldoc OUTPUT, #Customer_XML
--OPEN XML example of inserting multiple customers into a Table.
INSERT INTO CUSTOMER
(
First_Name
Middle_Name
Last_Name
)
SELECT
First_Name
,Middle_Name
,Last_Name
FROM OPENXML (#xmldoc, '/ArrayOfCustomers[1]/Customer',2)
WITH(
First_Name VARCHAR(50)
,Middle_Name VARCHR(50)
,Last_Name VARCHAR(50)
)
EXEC sp_xml_removedocument #xmldoc
END
You could just use an object Serialization class like this
public class Serialization
{
/// <summary>
/// Serializes the object.
/// </summary>
/// <param name="myObject">My object.</param>
/// <returns></returns>
public static XmlDocument SerializeObject(Object myObject)
{
XmlDocument XmlObject = new XmlDocument();
String XmlizedString = string.Empty;
try
{
MemoryStream memoryStream = new MemoryStream();
XmlSerializer xs = new XmlSerializer(myObject.GetType());
XmlTextWriter xmlTextWriter = new XmlTextWriter(memoryStream, Encoding.UTF8);
xs.Serialize(xmlTextWriter, myObject);
memoryStream = (MemoryStream)xmlTextWriter.BaseStream;
XmlizedString = UTF8ByteArrayToString(memoryStream.ToArray());
}
catch (Exception e)
{
System.Console.WriteLine(e);
}
XmlObject.LoadXml(XmlizedString);
return XmlObject;
}
/// <summary>
/// Deserializes the object.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="XmlizedString">The p xmlized string.</param>
/// <returns></returns>
public static T DeserializeObject<T>(String XmlizedString)
{
XmlSerializer xs = new XmlSerializer(typeof(T));
MemoryStream memoryStream = new MemoryStream(StringToUTF8ByteArray(XmlizedString));
//XmlTextWriter xmlTextWriter = new XmlTextWriter(memoryStream, Encoding.UTF8);
Object myObject = xs.Deserialize(memoryStream);
return (T)myObject;
}
/// <summary>
/// To convert a Byte Array of Unicode values (UTF-8 encoded) to a complete String.
/// </summary>
/// <param name="characters">Unicode Byte Array to be converted to String</param>
/// <returns>String converted from Unicode Byte Array</returns>
private static String UTF8ByteArrayToString(Byte[] characters)
{
UTF8Encoding encoding = new UTF8Encoding();
String constructedString = encoding.GetString(characters);
return (constructedString);
}
/// <summary>
/// Converts the String to UTF8 Byte array and is used in De serialization
/// </summary>
/// <param name="pXmlString"></param>
/// <returns></returns>
private static Byte[] StringToUTF8ByteArray(String pXmlString)
{
UTF8Encoding encoding = new UTF8Encoding();
Byte[] byteArray = encoding.GetBytes(pXmlString);
return byteArray;
}
}
then you don't have to build the XML by hand, plus you can use this with any item to transform it using XSLT
I would put the xml construction code inside the domain object. That way, you can just call obj.GetXML() from Web Service or data layer.
Related
So I am trying to deserialize and serialize a List.
The issue: The list(list1) is not saving to the file called "ListData" which should be created if not already there, into the documents folder in the android internal storage.
I think the file may not be creating properly or something, or the filepath is incorrect. Below is how it should be functioning but that isn't working as explained with the issue above.
I want to save the filename as something like "ListData".
Also, needs to be saved into the Internal Storage somewhere such as the Data folder of the app or Documents in internal storage.
The following is what i have for the code, but I can't seem to find any help elsewhere to fix my issue. It doesn't work, any ideas for a solution to what I want it to do?
Code:
public abstract class DataHandler
{
public static void SaveLists()
{
string filePath = Android.OS.Environment.DirectoryDocuments;
string fileName = "ListData";
XmlSerializer serializer = new XmlSerializer(typeof(List<Item>));
Stream writer = new FileStream(filePath, FileMode.Create);
serializer.Serialize(writer, _LISTFROMANOTHERCLASS_);
writer.Close();
}
public static void LoadLists()
{
string filePath = Android.OS.Environment.DirectoryDocuments;
string fileName = "ListData";
XmlSerializer serializer = new XmlSerializer(typeof(List<Item>));
Stream reader = new FileStream(filePath, FileMode.Open);
List<Item> list1 = new List<Item>();
list1 = (List<Item>) serializer.Deserialize(reader);
_LISTFROMANOTHERCLASS_ = list1;
reader.Close();
}
}
Hi I have written a class to do these but with JSON serlization check is it helps it uses MVVM Cross, It has code written to encrypt and decrypt data you can avoid these parts
public class PersistantStorageHelper<T>
{
IMvxFileStoreAsync _mvxFileStoreAsync;
IMvxFileStore _mvxFileStore;
EDEngine bcEngine = new EDEngine(new AesEngine(), Encoding.UTF8);
string currentkey_temp_dev = "AthulHarikumar00";//This static key is not being used it is a just a place holder
public PersistantStorageHelper() {
this._mvxFileStore = Mvx.Resolve<IMvxFileStore>();
this._mvxFileStoreAsync = Mvx.Resolve<IMvxFileStoreAsync>();
bcEngine.SetPadding(new Pkcs7Padding());
currentkey_temp_dev = Constants.PassPhrase.Substring(4, 12)+"Road";
}
/// <summary>
///
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public async Task<T> GetPersistantObject(T obj)
{
var fileName = (typeof(T).ToString().Replace(".", "_"));
var x= await GetPersistantObject(obj, fileName);
return x;
}
/// <summary>
/// If object exists returns the object else saves a plain object and returns it
/// </summary>
/// <param name="obj">empty placeholder object</param>
/// <returns>Filesystem object</returns>
public async Task<T> GetPersistantObject( T obj,string fileName) {
List<string> files = new List<string>(_mvxFileStore.GetFilesIn(_mvxFileStore.NativePath("")));
fileName = _mvxFileStore.NativePath(fileName);
if (!files.Contains(fileName))
{
var objJson = Newtonsoft.Json.JsonConvert.SerializeObject(obj);
objJson= bcEngine.Encrypt(objJson, currentkey_temp_dev);
await _mvxFileStoreAsync.WriteFileAsync(fileName,objJson);
}
else {
try
{
var temp = await _mvxFileStoreAsync.TryReadTextFileAsync(fileName);
var str = bcEngine.Decrypt(temp.Result, currentkey_temp_dev);
obj = Newtonsoft.Json.JsonConvert.DeserializeObject<T>(str);
}
catch(Exception e) {
var objJson = Newtonsoft.Json.JsonConvert.SerializeObject(obj);
objJson = bcEngine.Encrypt(objJson, currentkey_temp_dev);
await _mvxFileStoreAsync.WriteFileAsync(fileName, objJson);
}
}
return obj;
}
/// <summary>
///
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public async Task<T> SetPersistantObject(T obj)
{
var fileName = _mvxFileStore.NativePath(typeof(T).ToString().Replace(".", "_"));
var temp = await SetPersistantObject(obj, fileName);
return temp;
}
/// <summary>
/// Saves object to persistant storage with encryption
/// </summary>
/// <param name="obj">object to be stored</param>
/// <returns>Saved object</returns>
public async Task<T> SetPersistantObject(T obj,string fileName)
{
List<string> files = new List<string>(_mvxFileStore.GetFilesIn(_mvxFileStore.NativePath("")));
fileName = _mvxFileStore.NativePath(fileName);
var objJson = Newtonsoft.Json.JsonConvert.SerializeObject(obj);
objJson = bcEngine.Encrypt(objJson, currentkey_temp_dev);
await _mvxFileStoreAsync.WriteFileAsync(fileName, objJson);
return obj;
}
}
java.util.List is not serializable, but java.util.ArrayList is. So just change List to ArrayList on both sites (left before variablename and right for constructor). Also check if your Item implements Serializable
This question already has answers here:
How to save/restore serializable object to/from file?
(6 answers)
Closed 8 years ago.
I need to store some objects as XML files in order to save data and load it later.
I coded this and it works for me:
public static Project Load(String file)
{
using (var stream = System.IO.File.OpenRead(file))
{
var serializer = new XmlSerializer(typeof(Project));
return serializer.Deserialize(stream) as Project;
}
}
public static void Save(Project p, String file)
{
using (var writer = new System.IO.StreamWriter(file))
{
var serializer = new XmlSerializer(p.GetType());
serializer.Serialize(writer, p);
writer.Flush();
}
}
Now, I need to do this with other kind of objects and I don't really want to copy/paste these methods for every object class.
Is possible to pass the object class to methods and make these methods generic for any object class?
i usually use this both methods from https://stackoverflow.com/a/271423/1315444
hope this helps :D
/// <summary>Serializes an object of type T in to an xml string</summary>
/// <typeparam name="T">Any class type</typeparam>
/// <param name="obj">Object to serialize</param>
/// <returns>A string that represents Xml, empty otherwise</returns>
public static string XmlSerialize<T>(this T obj) where T : class, new()
{
if (obj == null) throw new ArgumentNullException("obj");
var serializer = new XmlSerializer(typeof(T));
using (var writer = new StringWriter())
{
serializer.Serialize(writer, obj);
return writer.ToString();
}
}
/// <summary>Deserializes an xml string in to an object of Type T</summary>
/// <typeparam name="T">Any class type</typeparam>
/// <param name="xml">Xml as string to deserialize from</param>
/// <returns>A new object of type T is successful, null if failed</returns>
public static T XmlDeserialize<T>(this string xml) where T : class, new()
{
if (xml == null) throw new ArgumentNullException("xml");
var serializer = new XmlSerializer(typeof(T));
using (var reader = new StringReader(xml))
{
try { return (T)serializer.Deserialize(reader); }
catch { return null; } // Could not be deserialized to this type.
}
}
then you can go with
Project p = new Project();
string result = p.XmlSerialize();
Project p2 = result.XmlDeserialize<Project>();
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 am creating a dynamic form where if I click on "Add", a new panel appears with a set of buttons.
In this panel, I would like to add a list which will remember how many buttons were created. Thus I thought realize a list, but I want to increment again even though that we restart the console.
May be there is a tip to put it in a XMLfile. In this way my strategy can be renamed with the max of what is present in the CSV, but I do not know how to record and how to increment...
Any idea?
public class SerialStrategyFuture
{
public string StrategyName { get; set; }
public string NumStrategy { get; set; }
}
public void CreateStrategyFuture()
{
ConsoleStrategyItem strategyItemFuture = new ConsoleStrategyItem();
strategyItemFuture.Location = new Point(3, 3);
futureContainer.Height += 85;
futureContainer.Controls.Add(strategyItemFuture);
SerialStrategyFuture strategyFuture = new SerialStrategyFuture();
strategyFuture.StrategyName = "Strat Future ";
strategyFuture.NumStrategy = "How to increment it ???";
XmlSerializer serializer = new XmlSerializer(typeof(SerialStrategyFuture));
TextWriter textWriter = new StreamWriter(#"C:\Users\...");
serializer.Serialize(textWriter,strategyFuture);
textWriter.Close();
ConsoleStrategyItem.Instance.txtStrategyName.Text = "Strat Future 1 ";
}
I am not sure if you can serialize the utureContainer.Controls List. Threfore, I would use this way:
Declare a List ouf your buttons:
List controlList = new List();
each time your users creates a new button:
controlList.add(strategyItemFuture);
Serialize the List when your program closes or another opportune moment:
Deserialize it when your program starts.
build a foreach loop which pulls the buttons from the deserialized List.
Here are the two methods I use to serialize / deserialize
/// <summary>
/// Serializes a file to a compressed XML file. If an error occurs, the exception is NOT caught.
/// </summary>
/// <typeparam name="T">The Type</typeparam>
/// <param name="obj">The object.</param>
/// <param name="fileName">Name of the file.</param>
public static void SerializeToXML<T>(T obj, string fileName)
{
try
{
XmlSerializer serializer = new XmlSerializer(typeof(T));
using (FileStream fs = new FileStream(fileName, FileMode.Create))
{
using (GZipStream compressor = new GZipStream(fs, CompressionMode.Compress))
{
serializer.Serialize(compressor, obj);
}
}
}
catch (Exception)
{
throw;
}
}
/// <summary>
/// Deserializes an object from XML.
/// </summary>
/// <typeparam name="T">The object</typeparam>
/// <param name="file">The file.</param>
/// <returns>
/// The deserialized object
/// </returns>
public static T DeserializeFromXml<T>(string file)
{
T result;
XmlSerializer ser = new XmlSerializer(typeof(T));
using (FileStream fs = new FileStream(file, FileMode.Open))
{
using (GZipStream decompressor = new GZipStream(fs, CompressionMode.Decompress))
{
result = (T)ser.Deserialize(decompressor);
return result;
}
}
}
}
Usage:
SerializeToXML(controlList , yourPath);
this.controlList = DeserializeFromXml<List<ConsoleStrategyItem>>(yourPath);
I am doing a little bit more than just storing the number of buttons, but this has the advantage that you can store more data when your buttons have more logic.
I have an object exposed through a web service that is consumed by another system. That system also uses that same WSDL to return back an object on demand to us. I was wondering if it was possible to take that same object and relay it back to a the original object?
I tried to do the following and it wouldn't actually cast it back with the object populated... Any help would be great!
Thank you!
Note The method code listed below was based off of http://www.dotnetjohn.com/articles.aspx?articleid=173
public void ConvertBack()
{
ThirdParty.Animal animal;
using (var svc = new ThirdPartySoapClient())
thirdPartyAnimal = svc.GetAnimal("Identifier");
var xml = SerializeObject(thirdPartyAnimal, typeof(ThirdParty.Animal));
var originalAnimal = (OriginalNamespace.Animal)DeserializeObject(xml, typeof(OrginalNamespace.Animal));
Assert.AreEqual(originalAnimal.Name, animal.Name);
}
/// <summary>
/// Method to convert a custom Object to XML string
/// </summary>
/// <param name="pObject">Object that is to be serialized to XML</param>
/// <param name="typeOfObject">typeof() object that is being passed to be serialized to XML</param>
/// <returns>XML string</returns>
public string SerializeObject(object pObject, Type typeOfObject)
{
try
{
var memoryStream = new MemoryStream();
var xs = new XmlSerializer(typeOfObject);
var xmlTextWriter = new XmlTextWriter(memoryStream, Encoding.UTF8);
xs.Serialize(xmlTextWriter, pObject);
memoryStream = (MemoryStream) xmlTextWriter.BaseStream;
var xmlizedString = UTF8ByteArrayToString(memoryStream.ToArray());
return xmlizedString;
}
catch (Exception e)
{
Console.WriteLine(e);
return null;
}
}
/// <summary>
/// Method to reconstruct an Object from XML string
/// </summary>
/// <param name="pXmlizedString">XML To Be Converted to an Object</param>
/// <param name="typeOfObject">typeof() object that is being passed to be serialized to XML</param>
/// <returns></returns>
public object DeserializeObject(string pXmlizedString, Type typeOfObject)
{
var xs = new XmlSerializer(typeOfObject);
var memoryStream = new MemoryStream(StringToUTF8ByteArray(pXmlizedString));
new XmlTextWriter(memoryStream, Encoding.UTF8);
return xs.Deserialize(memoryStream);
}
/// <summary>
/// To convert a Byte Array of Unicode values (UTF-8 encoded) to a complete String.
/// </summary>
/// <param name="characters">Unicode Byte Array to be converted to String</param>
/// <returns>String converted from Unicode Byte Array</returns>
private static string UTF8ByteArrayToString(Byte[] characters)
{
var encoding = new UTF8Encoding();
var constructedString = encoding.GetString(characters);
return (constructedString);
}
/// <summary>
/// Converts the String to UTF8 Byte array and is used in De serialization
/// </summary>
/// <param name="pXmlString"></param>
/// <returns></returns>
private static Byte[] StringToUTF8ByteArray(string pXmlString)
{
var encoding = new UTF8Encoding();
var byteArray = encoding.GetBytes(pXmlString);
return byteArray;
}
When generating the proxy from WSDL there is an option called "/sharetypes" which should solve this problem
You can use it from the command line tools or in the options area of the "Add Web Service" dialogs