两种类型之间的XML序列化(通用和Web服务类型)

时间:2013-12-17 12:45:27

标签: .net web-services xml-serialization .net-2.0

如何使用Xml序列化将公共对象转换为Web服务对象(相同的对象但不同的命名空间 - Web服务代理更改命名空间),以及从Web服务转换为公共对象。

下面的代码没有异常,但是反序列化的对象属性设置为默认值,而不是它们应具有的值。正如@Mark Gravel在下面的答案中指出的那样,这是因为当您序列化到Web服务对象时,它会添加额外的Xml命名空间。 我已经尝试了很多方法,例如使用Xml.Serialization.XmlSerializerNamespaces并在序列化时设置默认命名空间,但是我得到了相同的结果或做错了什么并且在反序列化时出现了Xml错误。

我意识到这比直接映射对象属性要慢(性能),但它非常大,我希望快速运行原型而不必每次都转换对象。有没有办法在反序列化和添加序列化时添加名称空间之前完全删除名称空间? - 添加和删除xmlns="http://[host.co.uk]/位的结构化方法。

注意,Web服务由第三方拥有(因此无法更改该代码),并且该对象没有特殊的Xml装饰。涉及多个Web服务,因此命名空间将在运行时更改,具体取决于服务URL。

要序列化我使用此代码:

Dim serializer As New Xml.Serialization.XmlSerializer(requestParams.GetType)
Using strWriter As New IO.StringWriter()
    serializer.Serialize(strWriter, requestParams)
    Return strWriter.ToString
End Using

要反序列化我使用此代码:

Dim serializer As New XmlSerializer(GetType(T))
Using strReader As New IO.StringReader(serializedXml)
    Return DirectCast(serializer.Deserialize(strReader), T)
End Using

供参考,序列化通用对象:

<?xml version="1.0" encoding="utf-16"?>
<SearchPartsRequest>
  <LocationCode>01</LocationCode>
  <PartCriteria>
    <PartNo>1064762</PartNo>
  </PartCriteria>
  <WildCardSearch>false</WildCardSearch>
</SearchPartsRequest>

序列化的Web服务对象:

<?xml version="1.0" encoding="utf-16"?>
<SearchPartsRequest xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <LocationCode xmlns="http://host.co.uk/">01</LocationCode>
  <PartCriteria xmlns="http://host.co.uk/">
    <PartNo>1064762</PartNo>
  </PartCriteria>
</SearchPartsRequest>

4 个答案:

答案 0 :(得分:1)

您可能需要考虑为所使用的命名空间自定义Serialize和Deserialize函数。如下所述: http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlattributes.xmlns(v=vs.110).aspx

答案 1 :(得分:0)

Xml命名空间。你的不匹配。您需要正确声明命名空间,例如:

[XmlElement(Namespace="http://host.co.uk/")]
public string LocationCode {get;set;}

答案 2 :(得分:0)

删除命名空间的最简单方法就是使用Regex。因此(在C#抱歉):

var newXml = System.Text.RegularExpressions.Regex.Replace(xml,@“(xmlns:?[^ =] = [”“] [^”“] [”“]) “,”“, System.Text.RegularExpressions.RegexOptions.IgnoreCase | System.Text.RegularExpressions.RegexOptions.Multiline);

答案 3 :(得分:0)

System.Xml.Serialization.XmlAttributes.Xmlns = False是关键。

以下是一个例子:

Dim atts As New System.Xml.Serialization.XmlAttributes()
' Set to true to preserve namespaces, or false to ignore them.
atts.Xmlns = False

Dim xover As New System.Xml.Serialization.XmlAttributeOverrides()
' Add the XmlAttributes and specify the name of  
' the element containing namespaces.
xover.Add(secCred.GetType, String.Empty, atts)

Dim serializer As New System.Xml.Serialization.XmlSerializer(secCred.GetType, xover)
Using strWriter As New IO.StringWriter()
    serializer.Serialize(strWriter, secCred)
    xml = strWriter.ToString
End Using

字符串xml将包含(注意xmlns="http://host.co.uk/"已被删除)并且可以反序列化为公共对象类型:

<SearchPartsRequest>
  <LocationCode>01</LocationCode>
  <PartCriteria>
    <PartNo>1064762</PartNo>
  </PartCriteria>
  <WildCardSearch>false</WildCardSearch>
</SearchPartsRequest>

反序列化似乎并不重要,您可以照常执行此操作,因为命名空间会自动为您添加(如果您再次序列化)。