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

时间:2013-11-12 15:29:09

标签: xml wcf wsdl

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

<Payload></Payload>

VS

&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)?

这是我解决这个问题的第三天,我开始失去希望。任何建议都将不胜感激。

2 个答案:

答案 0 :(得分: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;
    }
}

答案 1 :(得分: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)