XML反序列化为模型报错:SetPhoneStatus命名空间未预期如何解决
报错根因
反序列化失败的核心原因是XML中SetPhoneStatus节点声明了默认命名空间xmlns="http://tempuri.org/",但定义的TeliaMobileStatusModel类的XmlRoot特性没有指定对应命名空间,XmlSerializer反序列化时会严格校验节点命名空间,匹配失败就会抛出“SetPhoneStatus节点未被预期”的错误。
修复方案
按以下步骤调整即可:
给实体类补充正确的命名空间配置
给XmlRoot特性添加Namespace参数,和XML中的命名空间完全一致;如果需要读取XML里的timestamp字段,补充对应属性即可,不需要解析该字段也可以不添加。
修正后的实体类代码:<XmlRoot(ElementName:="SetPhoneStatus", Namespace:="http://tempuri.org/")> Public Class TeliaMobileStatusModel <XmlElement(ElementName:="msisdn")> Public Property MSISDN As String <XmlElement(ElementName:="status")> Public Property Status As String <XmlElement(ElementName:="timestamp")> Public Property Timestamp As String End Class注:子元素默认继承根节点的默认命名空间,不需要重复给每个
XmlElement指定Namespace参数。(可选优化)替换节点查找逻辑,避免匹配错误
原有逻辑用的GetElementsByTagName方法不会区分节点所属的命名空间和所在层级,如果XML中存在其他同名节点会出现匹配错误,建议用XmlNamespaceManager精准定位SOAP Body下的目标节点,优化后的反序列化函数代码:Public Function DeserializeXmlElement(Of T)(xml As XmlDocument, element As String) As T Try Dim nsmgr As New XmlNamespaceManager(xml.NameTable) nsmgr.AddNamespace("soap", "http://schemas.xmlsoap.org/soap/envelope/") nsmgr.AddNamespace("ns", "http://tempuri.org/") ' 精准定位SOAP Body下的目标节点 Dim targetNode = xml.SelectSingleNode($"//soap:Body/ns:{element}", nsmgr) If targetNode IsNot Nothing Then Dim serializer As New XmlSerializer(GetType(T)) Using reader As New IO.StringReader(targetNode.OuterXml) Return CType(serializer.Deserialize(reader), T) End Using End If Return Nothing Catch ex As Exception Debug.WriteLine(ex.ToString()) Return Nothing End Try End Function
调整完成后即可正常完成反序列化,拿到对应字段的值。
内容的提问来源于stack exchange,提问作者simo026q
相关产品推荐
相关产品推荐

