无法将 XML 反序列化为 C# 对象,我做错了什么?
Failed to Deserialize XML to C# object, what am I doing wrong?
嗨,我需要 反序列化 XML 到 Parameters class 的对象中。
我定义了这个执行序列化的通用函数:
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 我要反序列化的字符串:
<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>
键入 (class) 我想将我的 XML 反序列化为:
[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; }
}
我从代码调用 反序列化 函数,传递这个 XML:
var parameters = Utility.Deserialize<ParametersModel>(xml);
现在我没有得到异常,但是参数集合是空的
怎么了?
谢谢
更新1
<?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>
UserProfileState 下多了一个节点。
你们知道为什么我得到这个额外的节点,某些属性定义不正确吗?
更新2
我已经按照建议修改了目标对象 class,现在反序列化工作正常,唯一的问题是我必须将某些属性的类型从 bool 更改为 string ...现在我需要弄清楚如何保留 bool 属性并仍然进行转换....
[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; }
}
更新3
对于布尔属性,我实施了建议的解决方法,"Nullable" 属性 是 bool 类型,所以我必须定义额外的 属性 将字符串自动转换为 bool 并自动将 bool 转换为字符串.谢谢大家的建议。
[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; }
}
您可能缺少 XML header 标签,例如
<?xml version="1.0" encoding="utf-8"?>
您的问题是您已告诉它反序列化为 ParametersModel
类型的对象。您没有给出元素名称的提示,因此它使用 class 名称作为元素名称。如果您要更改 xml 以使根元素为 ParametersModel
,那么您会发现它不会再出错。但是,它也不会 return 您预期的结果,因为其他地方存在更多类似问题。
在评论中,Dan 建议从序列化开始最简单,他是对的。如果您尝试创建 ParametersModel
对象的实例,然后对其进行序列化,那么您将看到模型建议的名称和结构。如果您随后调整您的模型及其属性,直到输出符合您的预期,那么您就可以正确地反序列化 xml 文档。
从以下位置更改 ParametersModel 上的 XmlRootAttribute 声明:
[XmlRoot]
至:
[XmlRoot(ElementName = "Parameters")]
完整发布:
class Program
{
static void Main(string[] args)
{
var s = @"<Parameters>
<UserProfileState>1</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>";
var serializer = new XmlSerializer(typeof(ParametersModel));
using (var reader = new StringReader(s))
{
var result = (ParametersModel)serializer.Deserialize(reader);
var sb = new StringBuilder();
using (var writer = new StringWriter(sb))
{
serializer.Serialize(writer, result);
}
}
}
}
[Serializable]
[XmlRoot(ElementName ="Parameters")]
public class ParametersModel
{
[XmlElement]
public int UserProfileState { get; set; }
[XmlElement("Parameter")]
public List<ParameterModel> Parameters { get; set; }
}
[Serializable]
public class ParameterModel
{
[XmlElement]
public string Name { get; set; }
[XmlElement]
public string Type { get; set; }
[XmlElement]
public bool Nullable { get; set; }
[XmlElement]
public bool AllowBlank { get; set; }
[XmlElement]
public bool MultiValue { get; set; }
[XmlElement]
public bool UsedInQuery { get; set; }
[XmlElement]
public string State { get; set; }
[XmlElement]
public string Prompt { get; set; }
[XmlElement]
public bool DynamicPrompt { get; set; }
[XmlElement]
public bool PromptUser { get; set; }
[XmlElement]
public bool DynamicValidValues { get; set; }
[XmlElement]
public bool DynamicDefaultValue { get; set; }
}
如果您这样定义 类,则可以序列化 xml:
[Serializable]
[XmlRoot("Parameters")]
public class ParametersModel
{
[XmlElement]
public int UserProfileState { get; set; }
[XmlElement("Parameter")]
public List<ParameterModel> Parameters { get; set; }
}
但它不起作用,因为 XmlSerialize 无法将您的 False/True 解析为 bool 值。因此,您应该将所有 bool 属性更改为字符串,或者考虑使用 Microsoft 建议的解决方法:
https://blogs.msdn.microsoft.com/helloworld/2009/04/03/workaround-to-deserialize-true-false-using-xmlserializer/
我认为下面的内容应该会让你很接近。首先,你的 top-level class
[XmlRoot(nameof(Parameters))]
public sealed class ParametersModel
{
public int UserProfileState { get; set; }
[XmlElement("Parameter")]
public List<ParameterModel> Parameters { get; set; }
}
你的ParameterModel
class就是
public sealed class ParameterModel
{
public string Name { get; set; }
public string Type { get; set; }
public BooleanAsString Nullable { get; set; }
public BooleanAsString AllowBlank { get; set; }
public BooleanAsString MultiValue { get; set; }
public BooleanAsString UsedInQuery { get; set; }
public string State { get; set; }
public string Prompt { get; set; }
public BooleanAsString DynamicPrompt { get; set; }
public BooleanAsString PromptUser { get; set; }
public List<Dependency> Dependencies { get; set; }
public BooleanAsString DynamicValidValues { get; set; }
public BooleanAsString DynamicDefaultValue { get; set; }
}
public sealed class Dependency
{
[XmlText]
public string Value { get; set; }
}
我已经在实用程序中完成了 bool
/string
的工作 class
// https://blogs.msdn.microsoft.com/helloworld/2009/04/03/workaround-to-deserialize-true-false-using-xmlserializer/
public struct BooleanAsString
{
public BooleanAsString(bool value = default(bool))
{
StringValue = null;
Value = value;
}
public static implicit operator BooleanAsString(bool value)
{
return new BooleanAsString(value);
}
public static implicit operator bool(BooleanAsString value)
{
return value.Value;
}
[XmlIgnore]
public bool Value
{
get { return Boolean.Parse(StringValue); }
set { StringValue = value ? "True" : "False"; }
}
[XmlText]
public string StringValue { get; set; }
}
测试代码为:
static string XmlSerialize(Object o)
{
var serializer = new XmlSerializer(o.GetType());
using (var writer = new StringWriter())
{
serializer.Serialize(writer, o);
return writer.ToString();
}
}
static void Main(string[] args)
{
var parameters = new ParametersModel { UserProfileState = 0, Parameters = new List<ParameterModel>() };
parameters.Parameters.Add(new ParameterModel
{ Name = "County", Type = "String", Nullable = false, AllowBlank = false, MultiValue = true, UsedInQuery = true, State = "MissingValidValue", Prompt = "County", DynamicPrompt = false, PromptUser = true, DynamicValidValues = true, DynamicDefaultValue = true});
var pm = new ParameterModel
{ Name = "City", Type = "String", Nullable = false, AllowBlank = false, MultiValue = true, UsedInQuery = true, State = "MissingValidValue", Prompt = "City", DynamicPrompt = false, PromptUser = true, DynamicValidValues = true, DynamicDefaultValue = true };
pm.Dependencies = new List<Dependency>() { new Dependency{ Value = "Country" } };
parameters.Parameters.Add(pm);
var s = XmlSerialize(parameters);
}
生成以下 XML
<?xml version="1.0" encoding="utf-16"?>
<Parameters xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<UserProfileState>0</UserProfileState>
<Parameter>
<Name>County</Name>
<Type>String</Type>
<Nullable>False</Nullable>
<AllowBlank>False</AllowBlank>
<MultiValue>True</MultiValue>
<UsedInQuery>True</UsedInQuery>
<State>MissingValidValue</State>
<Prompt>County</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>
嗨,我需要 反序列化 XML 到 Parameters class 的对象中。
我定义了这个执行序列化的通用函数:
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 我要反序列化的字符串:
<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>
键入 (class) 我想将我的 XML 反序列化为:
[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; }
}
我从代码调用 反序列化 函数,传递这个 XML:
var parameters = Utility.Deserialize<ParametersModel>(xml);
现在我没有得到异常,但是参数集合是空的
怎么了?
谢谢
更新1
<?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>
UserProfileState 下多了一个节点。
你们知道为什么我得到这个额外的节点,某些属性定义不正确吗?
更新2
我已经按照建议修改了目标对象 class,现在反序列化工作正常,唯一的问题是我必须将某些属性的类型从 bool 更改为 string ...现在我需要弄清楚如何保留 bool 属性并仍然进行转换....
[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; }
}
更新3
对于布尔属性,我实施了建议的解决方法,"Nullable" 属性 是 bool 类型,所以我必须定义额外的 属性 将字符串自动转换为 bool 并自动将 bool 转换为字符串.谢谢大家的建议。
[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; }
}
您可能缺少 XML header 标签,例如
<?xml version="1.0" encoding="utf-8"?>
您的问题是您已告诉它反序列化为 ParametersModel
类型的对象。您没有给出元素名称的提示,因此它使用 class 名称作为元素名称。如果您要更改 xml 以使根元素为 ParametersModel
,那么您会发现它不会再出错。但是,它也不会 return 您预期的结果,因为其他地方存在更多类似问题。
在评论中,Dan 建议从序列化开始最简单,他是对的。如果您尝试创建 ParametersModel
对象的实例,然后对其进行序列化,那么您将看到模型建议的名称和结构。如果您随后调整您的模型及其属性,直到输出符合您的预期,那么您就可以正确地反序列化 xml 文档。
从以下位置更改 ParametersModel 上的 XmlRootAttribute 声明:
[XmlRoot]
至:
[XmlRoot(ElementName = "Parameters")]
完整发布:
class Program
{
static void Main(string[] args)
{
var s = @"<Parameters>
<UserProfileState>1</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>";
var serializer = new XmlSerializer(typeof(ParametersModel));
using (var reader = new StringReader(s))
{
var result = (ParametersModel)serializer.Deserialize(reader);
var sb = new StringBuilder();
using (var writer = new StringWriter(sb))
{
serializer.Serialize(writer, result);
}
}
}
}
[Serializable]
[XmlRoot(ElementName ="Parameters")]
public class ParametersModel
{
[XmlElement]
public int UserProfileState { get; set; }
[XmlElement("Parameter")]
public List<ParameterModel> Parameters { get; set; }
}
[Serializable]
public class ParameterModel
{
[XmlElement]
public string Name { get; set; }
[XmlElement]
public string Type { get; set; }
[XmlElement]
public bool Nullable { get; set; }
[XmlElement]
public bool AllowBlank { get; set; }
[XmlElement]
public bool MultiValue { get; set; }
[XmlElement]
public bool UsedInQuery { get; set; }
[XmlElement]
public string State { get; set; }
[XmlElement]
public string Prompt { get; set; }
[XmlElement]
public bool DynamicPrompt { get; set; }
[XmlElement]
public bool PromptUser { get; set; }
[XmlElement]
public bool DynamicValidValues { get; set; }
[XmlElement]
public bool DynamicDefaultValue { get; set; }
}
如果您这样定义 类,则可以序列化 xml:
[Serializable]
[XmlRoot("Parameters")]
public class ParametersModel
{
[XmlElement]
public int UserProfileState { get; set; }
[XmlElement("Parameter")]
public List<ParameterModel> Parameters { get; set; }
}
但它不起作用,因为 XmlSerialize 无法将您的 False/True 解析为 bool 值。因此,您应该将所有 bool 属性更改为字符串,或者考虑使用 Microsoft 建议的解决方法: https://blogs.msdn.microsoft.com/helloworld/2009/04/03/workaround-to-deserialize-true-false-using-xmlserializer/
我认为下面的内容应该会让你很接近。首先,你的 top-level class
[XmlRoot(nameof(Parameters))]
public sealed class ParametersModel
{
public int UserProfileState { get; set; }
[XmlElement("Parameter")]
public List<ParameterModel> Parameters { get; set; }
}
你的ParameterModel
class就是
public sealed class ParameterModel
{
public string Name { get; set; }
public string Type { get; set; }
public BooleanAsString Nullable { get; set; }
public BooleanAsString AllowBlank { get; set; }
public BooleanAsString MultiValue { get; set; }
public BooleanAsString UsedInQuery { get; set; }
public string State { get; set; }
public string Prompt { get; set; }
public BooleanAsString DynamicPrompt { get; set; }
public BooleanAsString PromptUser { get; set; }
public List<Dependency> Dependencies { get; set; }
public BooleanAsString DynamicValidValues { get; set; }
public BooleanAsString DynamicDefaultValue { get; set; }
}
public sealed class Dependency
{
[XmlText]
public string Value { get; set; }
}
我已经在实用程序中完成了 bool
/string
的工作 class
// https://blogs.msdn.microsoft.com/helloworld/2009/04/03/workaround-to-deserialize-true-false-using-xmlserializer/
public struct BooleanAsString
{
public BooleanAsString(bool value = default(bool))
{
StringValue = null;
Value = value;
}
public static implicit operator BooleanAsString(bool value)
{
return new BooleanAsString(value);
}
public static implicit operator bool(BooleanAsString value)
{
return value.Value;
}
[XmlIgnore]
public bool Value
{
get { return Boolean.Parse(StringValue); }
set { StringValue = value ? "True" : "False"; }
}
[XmlText]
public string StringValue { get; set; }
}
测试代码为:
static string XmlSerialize(Object o)
{
var serializer = new XmlSerializer(o.GetType());
using (var writer = new StringWriter())
{
serializer.Serialize(writer, o);
return writer.ToString();
}
}
static void Main(string[] args)
{
var parameters = new ParametersModel { UserProfileState = 0, Parameters = new List<ParameterModel>() };
parameters.Parameters.Add(new ParameterModel
{ Name = "County", Type = "String", Nullable = false, AllowBlank = false, MultiValue = true, UsedInQuery = true, State = "MissingValidValue", Prompt = "County", DynamicPrompt = false, PromptUser = true, DynamicValidValues = true, DynamicDefaultValue = true});
var pm = new ParameterModel
{ Name = "City", Type = "String", Nullable = false, AllowBlank = false, MultiValue = true, UsedInQuery = true, State = "MissingValidValue", Prompt = "City", DynamicPrompt = false, PromptUser = true, DynamicValidValues = true, DynamicDefaultValue = true };
pm.Dependencies = new List<Dependency>() { new Dependency{ Value = "Country" } };
parameters.Parameters.Add(pm);
var s = XmlSerialize(parameters);
}
生成以下 XML
<?xml version="1.0" encoding="utf-16"?>
<Parameters xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<UserProfileState>0</UserProfileState>
<Parameter>
<Name>County</Name>
<Type>String</Type>
<Nullable>False</Nullable>
<AllowBlank>False</AllowBlank>
<MultiValue>True</MultiValue>
<UsedInQuery>True</UsedInQuery>
<State>MissingValidValue</State>
<Prompt>County</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>