WCF端点未正确序列化XML

时间:2015-03-10 22:10:38

标签: c# xml json wcf

我在http://localhost:8090/api/Test有一个WCF端点。实现看起来有点像这样:

[OperationContract]
[WebInvoke(
    Method = "POST",
    BodyStyle = WebMessageBodyStyle.Bare,
    UriTemplate = "Test")]
void TestEndpoint(Test test);

我有一些在其他地方声明的数据对象

[DataContract]
public class TestBase
{
    [DataMember(Name = "BaseValue")]
    public string BaseValue { get; set; }
}
[DataContract(Namespace = "")]
public class Test : TestBase
{
    [DataMember(Name = "TestValue")]
    public string TestValue { get; set; }
}

我遇到的问题是当我调用端点并通过请求体传递对象数据时,数据只在我使用JSON时被正确序列化,而不是在我使用XML时。

以下内容非常棒。 Test.TestValue ==“TestValue”和Test.BaseValue ==“BaseValue”。

POST http://localhost:8090/api/Test
Content-Type: text/json

{ "TestValue":"Test", "BaseValue": "BaseValue" }

当我执行以下Test.TestValue ==“TestValue”和Test.BaseValue == null:(

POST http://localhost:8090/api/Test 
Content-Type: text/xml

<Test>  <TestValue>Test</TestValue>  <BaseValue>Base</BaseValue></Test>

关于我在这里做错了什么的想法?

1 个答案:

答案 0 :(得分:1)

首先,您需要将基类放在与派生类相同的名称空间中:

[DataContract(Namespace = "")]
public class TestBase
{
    [DataMember(Name = "BaseValue")]
    public string BaseValue { get; set; }
}

如果不这样做,BaseValue实际上将位于不同的命名空间中,即数据协定序列化程序选择的默认命名空间:

<Test xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
    <BaseValue xmlns="http://schemas.datacontract.org/2004/07/ClrNamespace">foo</BaseValue>
    <TestValue>bar</TestValue>
</Test>

(JSON没有对象名称空间,所以这不是问题。)

接下来,BaseValue 必须在XML中TestValue之前,因为data contract serializer对订单敏感。见Data Member Order

  

数据排序的基本规则包括:

     
      
  • 如果数据协定类型是继承层次结构的一部分,则其基本类型的数据成员始终位于订单中。

  •   
  • 接下来依次是当前类型的数据成员,它们没有按字母顺序设置DataMemberAttribute属性的Order属性。

  •   
  • 接下来是具有DataMemberAttribute属性集的Order属性的任何数据成员。它们首先按Order属性的值排序,然后按字母顺序排序,如果某个Order值有多个成员。可以跳过订单值。

  •   
     

通过调用CompareOrdinal方法建立字母顺序。

(相反,JSON对象属性定义为unordered,因此您不会遇到DataContractJsonSerializer的这种复杂情况。)

因此,在基类上添加了名称空间声明后,可以反序列化以下XML:

<Test>  <BaseValue>Base</BaseValue> <TestValue>Test</TestValue>  </Test>