WCF 终结点未正确序列化 XML

WCF endpoint not serializing XML correctly

我在 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 时正确序列化,而不是在我使用 [=36 时=].

以下将非常有效。 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>

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

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

[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 is order sensitive. See Data Member Order:

The basic rules for data ordering include:

  • If a data contract type is a part of an inheritance hierarchy, data members of its base types are always first in the order.

  • Next in order are the current type’s data members that do not have the Order property of the DataMemberAttribute attribute set, in alphabetical order.

  • Next are any data members that have the Order property of the DataMemberAttribute attribute set. These are ordered by the value of the Order property first and then alphabetically if there is more than one member of a certain Order value. Order values may be skipped.

Alphabetical order is established by calling the CompareOrdinal method.

(相比之下,JSON 对象属性被定义为 unordered, so you won't encounter this complication with DataContractJsonSerializer。)

因此,在基础 class 上添加命名空间声明后,可以反序列化以下 XML:

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