使用 WCF 发送具有未转义标记的 XML



我想使用 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 类型的参数,但是当我尝试这样做时,客户端代码说:"类型'字符串'的值无法转换为'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)

最新更新