我想使用 WCF 发送 XML,以便将记录插入内部数据库表。 此 XML 需要采用任何样式(而不是预先序列化为数据协定)。 此外,拥有此服务的重点是允许我们的任何客户端发送XML数据,这意味着通用输入方法是必须的(例如,对于那些不使用Visual Studio的客户)。尝试此操作时,XML 标记将被转义,从而有效地使使用的有效负载空间增加 50% 以上。
<Payload></Payload>
与
<Payload></Payload>
由于我想允许发送大量数据,并且由于使用的空间量较高(因为转义标签),因此这不切实际。
我尝试使用 CDATA 封装 ( <![CDATA[<Payload></Payload>]]>
),但是,标签仍然被转义 ( <![CDATA[<Payload></Payload>]]>
)。
从其他文章中,我知道您可以传递 XElement 类型的参数,但是当我尝试这样做时,客户端代码说:"类型'字符串'的值无法转换为'System.Xml.Linq.XElement'。 听起来它不允许那些不使用 VB.NET 或 C# 的人也使用此参数。
同样在其他文章中,人们说您可以使用Stream作为输入参数数据类型或字节数组。 但是,同样,那些没有 VB.NET 或 C# 的人无法使用这些数据类型。 如果他们也可以,强迫他们使用它们似乎真的不切实际。 XML 输入就是我想要求他们传入的全部内容。
是否有任何其他方法(当使用Web.Config文件而不是本地托管的服务器代码时)允许将任何XML作为参数发送,该参数可以作为纯XML输入,但同时使任何人都可以调用它(例如,没有Visual Studio的人)?
这是我研究这个解决方案的第三天,我开始失去希望。 任何建议将不胜感激。
如果 Web 服务定义将操作输入定义为字符串 (xsd:string),则 .net 框架将转义 XML 有效负载。 另一方面,如果使用 any (xsd:any) 的操作输入参数定义服务,则服务将不会转义 XML。
下面的代码示例演示具有 XmlAnyElementAttribute 的属性的定义:
[System.Xml.Serialization.XmlAnyElementAttribute(Order = 2)]
public System.Xml.XmlElement Any
{
get
{
return this.anyField;
}
set
{
this.anyField = value;
}
}
找到了对我有用的答案。
我发现使用XElement的输入数据类型是关键。 由于我不能指望它被普遍接受(例如,对于那些不使用Visual Studio并且无法创建XElement对象的人来说),我使用Fiddler来找出围绕常规POST的内容(使用XElement对象)。 然后,我将相同的包装器包装在一个字符串上,并使用HttpWebRequest发送数据。
Dim PreSendData As String = "<s:Envelope xmlns:s=""http://schemas.xmlsoap.org/soap/envelope/""><s:Body><ProcessXMLPayload_XElement xmlns=""http://tempuri.org/""><XML>"
Dim PostSendData As String = "</XML></ProcessXMLPayload_XElement></s:Body></s:Envelope>"
Dim thePayLoad As String = _
"<Payload xmlns="""">" & _
"<PayloadDetails>" & _
"<Dependencies>" & _
"<Dependency>" & _
"<ParentTable>Guests</ParentTable>" & _
"</Dependency>" & _
"</Dependencies>" & _
"</PayloadDetails>" & _
"</Payload>"
Dim myWriter As StreamWriter = Nothing
Dim url As String = "http://TestServer/webservices/TestService/TestService.svc/soapService"
Dim myReq As HttpWebRequest = DirectCast(WebRequest.Create(url), HttpWebRequest)
myReq.Method = "POST"
Dim xmlToPost As String = PreSendData & thePayLoad & PostSendData
myReq.ContentLength = xmlToPost.Length
myReq.ContentType = "text/xml; charset=utf-8"
myReq.Headers.Add("SOAPAction", """http://tempuri.org/IService/ProcessXMLPayload_XElement""")
Try
myWriter = New StreamWriter(myReq.GetRequestStream())
' POST to the server
myWriter.Write(xmlToPost)
Catch e As Exception
Console.WriteLine(e.Message)
Finally
myWriter.Close()
End Try
Dim objResponse As HttpWebResponse = DirectCast(myReq.GetResponse(), HttpWebResponse)
Dim result As String
Using sr As New StreamReader(objResponse.GetResponseStream())
' read the response
result = sr.ReadToEnd()
sr.Close()
End Using
' send response to the console
Console.WriteLine(result)