Hi I need to deserialize XML into object of Parameters class.
I defined this generic function that does the serialization:
public static T Deserialize<T>(string xml) where T : class { XmlSerializer serializer = new XmlSerializer(typeof(T)); using (StringReader reader = new StringReader(xml)) { return (T)serializer.Deserialize(reader); } } XML string I want to deserialize:
<Parameters> <UserProfileState>0</UserProfileState> <Parameter> <Name>Country</Name> <Type>String</Type> <Nullable>False</Nullable> <AllowBlank>False</AllowBlank> <MultiValue>True</MultiValue> <UsedInQuery>True</UsedInQuery> <State>MissingValidValue</State> <Prompt>Country</Prompt> <DynamicPrompt>False</DynamicPrompt> <PromptUser>True</PromptUser> <DynamicValidValues>True</DynamicValidValues> <DynamicDefaultValue>True</DynamicDefaultValue> </Parameter> <Parameter> <Name>City</Name> <Type>String</Type> <Nullable>False</Nullable> <AllowBlank>False</AllowBlank> <MultiValue>True</MultiValue> <UsedInQuery>True</UsedInQuery> <State>MissingValidValue</State> <Prompt>City</Prompt> <DynamicPrompt>False</DynamicPrompt> <PromptUser>True</PromptUser> <Dependencies> <Dependency>Country</Dependency> </Dependencies> <DynamicValidValues>True</DynamicValidValues> <DynamicDefaultValue>True</DynamicDefaultValue> </Parameter> </Parameters> Type (class) I want to deserialize my XML into:
[Serializable, XmlRoot(ElementName = "Parameters")] public class ParametersModel { [XmlElement(ElementName = "UserProfileState")] public int UserProfileState { get; set; } [XmlArray(ElementName = "Parameter")] public List<ParameterModel> Parameter { get; set; } } [Serializable] public class ParameterModel { [XmlElement(ElementName = "Name")] public string Name { get; set; } [XmlElement(ElementName = "Type")] public string Type { get; set; } [XmlElement(ElementName = "Nullable")] public bool Nullable { get; set; } [XmlElement(ElementName = "AllowBlank")] public bool AllowBlank { get; set; } [XmlElement(ElementName = "MultiValue")] public bool MultiValue { get; set; } [XmlElement(ElementName = "UsedInQuery")] public bool UsedInQuery { get; set; } [XmlElement(ElementName = "State")] public string State { get; set; } [XmlElement(ElementName = "Prompt")] public string Prompt { get; set; } [XmlElement(ElementName = "DynamicPrompt")] public bool DynamicPrompt { get; set; } [XmlElement(ElementName = "PromptUser")] public bool PromptUser { get; set; } [XmlElement(ElementName = "DynamicValidValues")] public bool DynamicValidValues { get; set; } [XmlElement(ElementName = "DynamicDefaultValue")] public bool DynamicDefaultValue { get; set; } } I call my Deserialize function from code, passing this XML:
var parameters = Utility.Deserialize<ParametersModel>(xml); Now I dont get an exception, but Parameter collection is Empty
What is wrong?
Thank you
UPDATE1
<?xml version="1.0" encoding="utf-16"?> <Parameters xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <UserProfileState>0</UserProfileState> <Parameters> <Parameter /> <Parameter /> </Parameters> </Parameters> There is an extra node under UserProfileState.
Do you guys know why I get this extra node, some attribute is defined incorrectly?
UPDATE2
I have modified the target object class as was suggested into this, and the deserialization now works fine, with the only problem is that I had to change type from bool to string for some properties... now I need to figure out how to keep bool properties and still have conversion working....
[Serializable] [XmlRoot(ElementName = "Parameters")] public class ParametersModel { [XmlElement(ElementName = "UserProfileState")] public int UserProfileState { get; set; } [XmlElement(ElementName = "Parameter")] public List<ParameterModel> Parameters { get; set; } } [Serializable] public class ParameterModel { [XmlElement(ElementName = "Name")] public string Name { get; set; } [XmlElement(ElementName = "Type")] public string Type { get; set; } [XmlElement(ElementName = "Nullable")] public string Nullable { get; set; } [XmlElement(ElementName = "AllowBlank")] public string AllowBlank { get; set; } [XmlElement(ElementName = "MultiValue")] public string MultiValue { get; set; } [XmlElement(ElementName = "UsedInQuery")] public string UsedInQuery { get; set; } [XmlElement(ElementName = "State")] public string State { get; set; } [XmlElement(ElementName = "Prompt")] public string Prompt { get; set; } [XmlElement(ElementName = "DynamicPrompt")] public string DynamicPrompt { get; set; } [XmlElement(ElementName = "PromptUser")] public string PromptUser { get; set; } [XmlElement(ElementName = "DynamicValidValues")] public string DynamicValidValues { get; set; } [XmlElement(ElementName = "DynamicDefaultValue")] public string DynamicDefaultValue { get; set; } } UPDATE3
For boolean properties I implemented suggested workaround, "Nullable" property is of type bool, so I had to define additional property that will translate string to bool and bool to string automatically. Thank you guys for this suggestion.
[Serializable] public class ParameterModel { [XmlElement(ElementName = "Name")] public string Name { get; set; } [XmlElement(ElementName = "Type")] public string Type { get; set; } [XmlIgnore] public bool Nullable { get; set; } [XmlElement("Nullable")] public string NullableSerialize { get { return this.Nullable.ToString(); } set { this.Nullable = Convert.ToBoolean(value); } } [XmlElement(ElementName = "AllowBlank")] public string AllowBlank { get; set; } [XmlElement(ElementName = "MultiValue")] public string MultiValue { get; set; } [XmlElement(ElementName = "UsedInQuery")] public string UsedInQuery { get; set; } [XmlElement(ElementName = "State")] public string State { get; set; } [XmlElement(ElementName = "Prompt")] public string Prompt { get; set; } [XmlElement(ElementName = "DynamicPrompt")] public string DynamicPrompt { get; set; } [XmlElement(ElementName = "PromptUser")] public string PromptUser { get; set; } [XmlElement(ElementName = "DynamicValidValues")] public string DynamicValidValues { get; set; } [XmlElement(ElementName = "DynamicDefaultValue")] public string DynamicDefaultValue { get; set; } } 
<Parameters xmlns=''> was not expected.<Paramaters>element but it doesn't have that xmlns thing on it so I am not sure the message is as helpful as you seem to think. I would imagine OP is thinking "Well that is the start of my XML. What is it expecting if not that?"