0

我想使用 WCF 发送 XML 以将记录插入到内部数据库表中。此 XML 需要采用任何样式(不作为数据合同预先序列化)。此外,拥有此服务的目的是允许我们的任何客户发送 XML 数据,这意味着必须使用通用输入法(例如,对于那些不使用 Visual Studio 的客户)。尝试此操作时,XML 标记被转义,有效地使使用的有效负载空间增加了 50% 以上。

<Payload></Payload>

对比

&lt;Payload&gt;&lt;/Payload&gt;

由于我想允许发送大量数据,并且由于使用了更多的空间(因为转义标签),所以这是不切实际的。

我尝试使用 CDATA 封装(<![CDATA[<Payload></Payload>]]>),但是,标签仍然被转义(&lt;![CDATA[&lt;Payload&gt;&lt;/Payload&gt;]]&gt;)。

从其他文章中,我了解到您可以传递 XElement 类型的参数,但是当我尝试这样做时,客户端代码说:“'String' 类型的值无法转换为'System.Xml.Linq.XElement'。” 听起来它不允许那些不使用 VB.NET 或 C# 的人也使用此参数。

同样从其他文章中,人们说您可以使用 Stream 作为输入参数数据类型或字节数组。然而,那些没有 VB.NET 或 C# 的人也不能使用这些数据类型。如果他们也可以,那么强迫他们使用它们似乎并不实际。XML 输入就是我想让他们传入的所有内容。

是否有任何其他方式(当使用 Web.Config 文件而不是本地托管的服务器代码时)允许将任何 XML 作为可以作为纯 XML 输入的参数发送,但同时使任何人都可以调用它(例如,谁没有 Visual Studio)?

这是我研究这个解决方案的第三天,我开始失去希望。任何建议将不胜感激。

4

2 回答 2

1

找到了对我有用的答案。

我发现使用 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)
于 2013-11-14T00:04:31.460 回答
1

如果 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;
    }
}
于 2013-11-12T19:40:26.277 回答