ErocM ErocM - 16 days ago 3
C# Question

Deserialize giving an error on xml that serialization created

I have created a test to read and write to a license file. Granted, this is a weak licensing but it will work for what we need if I can get it to work.

I found this blog that had serialization of a class so I could save it to a file. Here is the site I got the help from:

http://codehandbook.org/c-object-xml/

So, I am taking my class, creating xml out of it, then encrypting it and saving it to a file. This part seems to work fine.

My xml that it creates:

<?xml version=\"1.0\" encoding=\"utf-16\"?>
<ArrayOfCheckObject xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">

<CheckObject>
<Program>Software1</Program>
<CompanyCode>1234</CompanyCode>
<WorkstationId>AA</WorkstationId>
<HardwareId>askldasldfj123234</HardwareId>
</CheckObject>

<CheckObject>
<Program>Software2</Program>
<CompanyCode>23456</CompanyCode>
<WorkstationId>BB</WorkstationId>
<HardwareId>askldwwwwwwwwwww</HardwareId>
</CheckObject>

<CheckObject>
<Program>Software3</Program>
<CompanyCode>4567</CompanyCode>
<WorkstationId>CC</WorkstationId>
<HardwareId>qqqqqqqq123234</HardwareId>
</CheckObject>

</ArrayOfCheckObject>


I formatted it for readability.

The next step that I was testing was to read it from the file, decrypt it, and then convert the xml to my class. The conversion to my class seems to be where the error is coming from at this line:

obj = serializer.Deserialize(xmlReader); // <--- error occurs here!!


My error:

{System.InvalidOperationException: There is an error in XML document (1, 41). ---> System.InvalidOperationException: <ArrayOfCheckObject xmlns=''> was not expected.
at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderCheckObject.Read3_CheckObject()
--- End of inner exception stack trace ---
at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle, XmlDeserializationEvents events)
at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader)
at ObjectCheck.XmlHelper.ObjectToXml(String xml, Type objectType) in c:\tgsource\Suburban Projects\ObjectCheck\ObjectCheck\XmlHelper.cs:line 46}


This is the XmlHelper class:

using System;
using System.IO;
using System.Xml;
using System.Xml.Serialization;

namespace ObjectCheck
{
internal static class XmlHelper
{
public static string GetXmlFromObject(object o)
{
StringWriter sw = new StringWriter();
XmlTextWriter tw = null;
try
{
XmlSerializer serializer = new XmlSerializer(o.GetType());
tw = new XmlTextWriter(sw);
serializer.Serialize(tw, o);
}
catch (Exception ex)
{
throw;
}
finally
{
sw.Close();
if (tw != null)
{
tw.Close();
}
}
return sw.ToString();
}

public static Object ObjectToXml(string xml, Type objectType)
{
StringReader strReader = null;
XmlSerializer serializer = null;
XmlTextReader xmlReader = null;
Object obj = null;
try
{
strReader = new StringReader(xml);
serializer = new XmlSerializer(objectType);
xmlReader = new XmlTextReader(strReader);
obj = serializer.Deserialize(xmlReader); // <--- error occurs here!!

}
catch (Exception ex)
{
//Handle Exception Code
}
finally
{
if (xmlReader != null)
{
xmlReader.Close();
}
if (strReader != null)
{
strReader.Close();
}
}
return obj;
}

}
}


My EncryptionHelper class:

using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

namespace ObjectCheck
{
internal static class EncryptionHelper
{

public static string Encrypt(string clearText)
{
string EncryptionKey = "12345";
byte[] clearBytes = Encoding.Unicode.GetBytes(clearText);
using (Aes encryptor = Aes.Create())
{
Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 });
encryptor.Key = pdb.GetBytes(32);
encryptor.IV = pdb.GetBytes(16);
using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateEncryptor(), CryptoStreamMode.Write))
{
cs.Write(clearBytes, 0, clearBytes.Length);
cs.Close();
}
clearText = Convert.ToBase64String(ms.ToArray());
}
}
return clearText;
}
public static string Decrypt(string cipherText)
{
string EncryptionKey = "12345";
cipherText = cipherText.Replace(" ", "+");
byte[] cipherBytes = Convert.FromBase64String(cipherText);
using (Aes encryptor = Aes.Create())
{
Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 });
encryptor.Key = pdb.GetBytes(32);
encryptor.IV = pdb.GetBytes(16);
using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateDecryptor(), CryptoStreamMode.Write))
{
cs.Write(cipherBytes, 0, cipherBytes.Length);
cs.Close();
}
cipherText = Encoding.Unicode.GetString(ms.ToArray());
}
}
return cipherText;
}


}
}


My main class to test the above classes:

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;

namespace ObjectCheck
{
public class CheckObject
{
public string Program { set; get; }
public string CompanyCode { set; get; }
public string WorkstationId { set; get; }
public string HardwareId { set; get; }

}

public static class ObjectCheck
{
public static Guid Check(CheckObject checkObject)
{
return CheckValue(checkObject);
}

private static Guid CheckValue(CheckObject checkObject)
{
switch (checkObject.Program.ToLower())
{
case "software1":
SaveObjectCheck();
return CheckPropane(checkObject);
break;

default:
return Guid.NewGuid();
break;
}
}

private static void SaveObjectCheck()
{
var obj = new List<CheckObject>();

var obj1 = new CheckObject();
obj1.Program = "Software1";
obj1.CompanyCode = "1234";
obj1.HardwareId = "askldasldfj123234";
obj1.WorkstationId = "AA";
obj.Add(obj1);

var obj2 = new CheckObject();
obj2.Program = "Software2";
obj2.CompanyCode = "2345";
obj2.HardwareId = "askldwwwwwwwwwww";
obj2.WorkstationId = "BB";
obj.Add(obj2);

var obj3 = new CheckObject();
obj3.Program = "Software3";
obj3.CompanyCode = "3456";
obj3.HardwareId = "qqqqqqqq123234";
obj3.WorkstationId = "CC";
obj.Add(obj3);

var xml = XmlHelper.GetXmlFromObject(obj);
var encxml = EncryptionHelper.Encrypt(xml);

using (var sw = new StreamWriter(@"c:\test\ObjectCheck.dat"))
{
sw.Write(encxml);
}

}

private static Guid CheckPropane(CheckObject checkObject)
{
var file = @"c:\test\ObjectCheck.dat";
var readfile = String.Empty;

using (var sr = new StreamReader(file))
{
var read = sr.ReadToEnd();
readfile = EncryptionHelper.Decrypt(read);
}

if (string.IsNullOrEmpty(readfile))
{
return Guid.Empty;
}

//byte[] byteArray = Encoding.UTF8.GetBytes(readfile);
//byte[] byteArray = Encoding.ASCII.GetBytes(contents);
//MemoryStream stream = new MemoryStream(byteArray);

CheckObject mco;
//using (TextReader reader = new StreamReader(readfile))
//{
// XmlSerializer serializer = new XmlSerializer(typeof(CheckObject));
// mco = (CheckObject)serializer.Deserialize(stream);
//}

var co = XmlHelper.ObjectToXml(readfile, typeof(CheckObject));
return Guid.Empty;

}

}

}


Any suggestions?

Answer

You are derializing it into the wrong type. It has to be the same type you serialized which is List<CheckObject>:

var co = XmlHelper.ObjectToXml(readfile, typeof(List<CheckObject>));

Serializing a List<CheckObject>

var obj = new List<CheckObject>();
// ...
var xml = XmlHelper.GetXmlFromObject(obj);

Deserializing as CheckObject (not going to work)

var co = XmlHelper.ObjectToXml(readfile, typeof(CheckObject));