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; }
}