将CDATA与WCF REST入门工具包一起使用

我有一个使用WCF REST入门套件的预览2构建的服务,但是我遇到了在调用中传递XML样式数据的问题。 这是我的请求对象:

[DataContract(Namespace = "")] public class ServiceRequest { [DataMember] public string ContentText { get; set; } [DataMember] public string ApiKey { get; set; } } 

一切正常,直到你扔进那里。 是否有将ContentText属性封装在CDATA或类似的东西中?

Marc Gravell 在这里提供了一个用于序列化CDATA部分的解决方案。

我在这里复制了代码以供后代使用。

更新:前面的示例没有生成有效的模式,XmlSchemaProviderAttribute和附带的方法将生成“xs:string”,它可以工作[更多…]

 using System; using System.IO; using System.Runtime.Serialization; using System.Xml; using System.Xml.Serialization; using System.ComponentModel; [XmlSchemaProvider("GenerateSchema")] public sealed class CDataWrapper : IXmlSerializable { // implicit to/from string public static implicit operator string(CDataWrapper value) { return value == null ? null : value.Value; } public static implicit operator CDataWrapper(string value) { return value == null ? null : new CDataWrapper { Value = value }; } public System.Xml.Schema.XmlSchema GetSchema() { return null; } // return "xs:string" as the type in scheme generation public static XmlQualifiedName GenerateSchema(XmlSchemaSet xs) { return XmlSchemaType.GetBuiltInSimpleType(XmlTypeCode.String).QualifiedName; } // "" =>  // "Foo" =>  public void WriteXml(XmlWriter writer) { if (!string.IsNullOrEmpty(Value)) { writer.WriteCData(Value); } } //  => "" //  => "" // Foo => "Foo" //  => "Foo" public void ReadXml(XmlReader reader) { if (reader.IsEmptyElement) { Value = ""; } else { reader.Read(); switch (reader.NodeType) { case XmlNodeType.EndElement: Value = ""; // empty after all... break; case XmlNodeType.Text: case XmlNodeType.CDATA: Value = reader.ReadContentAsString(); break; default: throw new InvalidOperationException("Expected text/cdata"); } } } // underlying value public string Value { get; set; } public override string ToString() { return Value; } } // example usage [DataContract(Namespace="http://myobjects/")] public sealed class MyType { public string SomeValue { get; set; } [DataMember(Name = "SomeValue", EmitDefaultValue = false)] private CDataWrapper SomeValueCData { get { return SomeValue; } set { SomeValue = value; } } public string EmptyTest { get; set; } [DataMember(Name = "EmptyTest", EmitDefaultValue = false)] private CDataWrapper EmptyTestCData { get { return EmptyTest; } set { EmptyTest = value; } } public string NullTest { get; set; } [DataMember(Name = "NullTest", EmitDefaultValue = false)] private CDataWrapper NullTestCData { get { return NullTest ; } set { NullTest = value; } } } // test rig static class Program { static void Main() { DataContractSerializer dcs = new DataContractSerializer(typeof(MyType)); StringWriter writer = new StringWriter(); using (XmlWriter xw = XmlWriter.Create(writer)) { MyType foo = new MyType { SomeValue = @"& 

在接受的答案中转换CDataWrapper的VB:

 Imports System Imports System.IO Imports System.Runtime.Serialization Imports System.Xml Imports System.Xml.Schema Imports System.Xml.Serialization Imports System.ComponentModel Public Class CDataWrapper Implements IXmlSerializable 'underlying value Public Property Value As String 'Implicit to/from string Public Shared Widening Operator CType(ByVal value As CDataWrapper) As String If value Is Nothing Then Return Nothing Else Return value.Value End If End Operator Public Shared Widening Operator CType(value As String) As CDataWrapper If value Is Nothing Then Return Nothing Else Return New CDataWrapper() With {.Value = value} End If End Operator Public Function GetSchema() As XmlSchema Implements IXmlSerializable.GetSchema Return Nothing End Function '  => "" '  => "" ' Foo => "Foo" '  => "Foo" Public Sub ReadXml(reader As XmlReader) Implements IXmlSerializable.ReadXml If reader.IsEmptyElement Then Me.Value = "" Else reader.Read() Select Case reader.NodeType Case XmlNodeType.EndElement Me.Value = "" ' empty after all... Case XmlNodeType.Text, XmlNodeType.CDATA Me.Value = reader.ReadContentAsString() Case Else Throw New InvalidOperationException("Expected text/cdata") End Select End If End Sub ' "" =>  ' "Foo" =>  Public Sub WriteXml(writer As XmlWriter) Implements IXmlSerializable.WriteXml If Not String.IsNullOrEmpty(Me.Value) Then writer.WriteCData(Me.Value) End If End Sub Public Overrides Function ToString() As String Return Me.Value End Function End Class 

上面的代码缺少这样一个事实,即您必须在阅读完之后浏览内容。 因此,这个类目前不适用于集合。

将其更改为以下内容,您现在可以保存CDataWrapper

 Value = reader.ReadContentAsString(); reader.Read(); 

虽然这是一个较旧的post,这里是我的2¢。 我通过将数据成员定义为XmlElement来解决此问题。

  [DataMember(Name = "MyCData")] public XmlElement MyCDataField { get; set; }