Reputation: 71
This questions was asked before but the answer doesn't work for me: so here is the question again : )
I am having real trouble trying to deserialize some XML and was hoping someone can offer some assistance. I have read a lot of similar posts but I am unable to resolve this.
Here is the XML
<register-account success="false">
<user-name>xxxxx</user-name>
<password>fghgh</password>
<email>[email protected]</email>
</register-account>
Class I am trying to deserialize to:
[Serializable, XmlRoot(ElementName = "register-account", Namespace = "MyNamespace")]
[XmlType("register-account")]
public class RegisterAccountResponse
{
[XmlAttribute("success")]
public bool Success { get; set; }
/// <summary>
/// Gets or sets the Tennant email address
/// </summary>
[XmlElement("email")]
public string Email { get; set; }
/// <summary>
/// Gets or sets the tennant password
/// </summary>
[XmlElement("password")]
public string Password { get; set; }
/// <summary>
/// Gets or sets the Tennant username
/// </summary>
[XmlElement("user-name")]
public string Username { get; set; }
}
Deserialization Method
public static T Deserialize<T>(string data) where T : class
{
var ser = new XmlSerializer(typeof(T));
using (var sr = new StringReader(data))
{
return (T)ser.Deserialize(sr);
}
}
Deserialization Method Call
var data = Helper.Deserialize<RegisterAccountResponse>(xml);
Exception:
There is an error in XML document (1, 2). ---> System.InvalidOperationException: was not expected. at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderData.Read5_data()
Inner Exception as follows:
<register-account xmlns=''> was not expected.
The answer to the question was to remove the namespace from the class (remove Namespace = "MyNamespace"). The class however is part of a very large library that is autogenerated using xsd.exe. I don't want to change anything in the generated class. Is there away to still fix this issue without having to modify the class?
Upvotes: 3
Views: 2576
Reputation: 192657
Is there away to still fix this issue without having to modify the class?
Yes.
.NET has a class called XmlAttributeOverrides that is designed for this purpose. You can override attributes that are present in the code, at runtime.
The following modified Deserialize utility method will correctly deserialize an instance of the class you provided, using the XML you provided, without requiring a modification of either. No XSLT either.
public static T DeserializeWithNoRootNamespace<T>(string data)
where T : class
{
/* Each overridden field, property, or type requires
an XmlAttributes object. We are overriding the serialization
of the XmlRoot on the type, so we need one XmlAttributes collection. */
var attrs = new XmlAttributes();
/* Create an XmlRootAttribute to override the XmlRoot in-line attr.
The override will use no namespace. */
var root = new XmlRootAttribute("register-account");
// set the XmlRoot on the XmlAttributes collection.
attrs.XmlRoot= root;
// Create the XmlAttributeOverrides object.
var o = new XmlAttributeOverrides();
/* Map the attributes collection to the thing being
overriden (the class). */
o.Add(typeof(T), attrs);
// create the serializer, specifying the overrides to use
var ser = new XmlSerializer(typeof(T), o);
using (var sr = new StringReader(data))
{
return (T)ser.Deserialize(sr);
}
}
The above code overrides the XmlRoot attribute. The XmlAttributeOverrides is general enough to allow overriding the xml-serialization attributes on any piece of the class to be deserialized. That wasn't necessary in your case.
ps: The [Serializable]
attribute you have decorating your class, is not needed. It is a common error, to apply that to classes that will be XML- serialized and deserialized. But it is extraneous, and therefore wrong.
Upvotes: 6
Reputation: 4585
Well if you can't or don't want to change the code then you must you xslt to transform your xml to add some namespaces where needed. that will help deserializer to deserialize document.
Regards.
Upvotes: -2