无法在VB.NET中反序列化XML

时间:2017-02-01 09:28:30

标签: asp.net xml vb.net asp.net-web-api msxml

我正在尝试从VBA for Excel程序中查询VB.NET中的RESTful API。

但是,我似乎无法正确地反序列化XML。

在VBA端,代码如下:

Set objHTTP = CreateObject("MSXML2.ServerXMLHTTP")
URL = "http://localhost:50261/api/values"
objHTTP.Open "POST", URL, False
objHTTP.setRequestHeader "User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0;Windows NT 5.0)"
objHTTP.setRequestHeader "Content-type", "application/xml"
objHTTP.send ("<?xml version=""1.0"" encoding=""UTF-8""?><KPISheet><site>mysite</site><unit>myunit</unit></KPISheet>)")

正如您所看到的,我发送的是我认为格式良好且非常简单的XML文档。

在VB.NET方面,我有一个名为KPISheet的类:

Public Class KPISheet
    Public Site As String
    Public Unit As String
End Class

和一个WebAPI,获得'POST':

Public Sub PostValue(<FromBody> oKPISheet As KPISheet)
    Debug.Print("toto")
End Sub

如果我在Debug行中设置断点,我可以看到oKPISheet是Nothing,XML文件没有反序列化。

在“输出”窗口中,出现以下错误消息:

抛出异常:System.Runtime.Serialization.dll中的“System.Runtime.Serialization.SerializationException”

我曾尝试使用和不使用标签,但我无法让它工作。

1 个答案:

答案 0 :(得分:1)

  

正如您所看到的,我发送的是我认为格式良好且非常简单的XML文档。

不幸的是你的假设是错误的:

<KPISheet>site>mysite</site>

那个无效的XML。您缺少网站代码的开头<。您似乎还有一些结束)作为XML中的最后一个字符。

所以你可以尝试发送有效的XML:

objHTTP.send("<?xml version=""1.0"" encoding=""UTF-8""?><KPISheet><site>mysite</site><unit>myunit</unit></KPISheet>")

另请注意,正确的内容类型应为text/xml而不是application/xml

objHTTP.setRequestHeader "Content-type", "text/xml"

另请注意,XML区分大小写,因此您应该将标记名称大写以匹配您的属性名称:

objHTTP.send("<?xml version=""1.0"" encoding=""UTF-8""?><KPISheet><Site>mysite</Site><Unit>myunit</Unit></KPISheet>")

最后但并非最不重要的是,Web API默认使用datacontract序列化程序来处理XML,因此您需要包含名称空间:

objHTTP.send("<?xml version=""1.0"" encoding=""UTF-8""?><KPISheet xmlns:i=""http://www.w3.org/2001/XMLSchema-instance"" xmlns=""http://schemas.datacontract.org/2004/07/WebApplication1.ViewModels.KPISheet""><Site>mysite</Site><Unit>myunit</Unit></KPISheet>")

请勿忘记调整命名空间以匹配您的KPISheet类。

或者,如果您不想包含名称空间,可以切换正在使用的XML序列化程序:

config.Formatters.XmlFormatter.UseXmlSerializer = true;

如果您想继续使用数据合同序列化程序,可以使用相应的属性修饰视图模型:

<DataContract(Namespace="")>
Public Class KPISheet
    <DataMember>
    Public Site As String
    <DataMember>
    Public Unit As String
End Class