1

这是问题的简化。

我有 Bar、Bar1 和 Bar2 类型的 DataContract。

[DataContract]
[Serializable]
[KnownType(typeof(Bar1))]
[KnownType(typeof(Bar2))]
public class Bar
{
    Public int SomeVal{get;set;}
}

[DataContract]
[Serializable]
public class Bar1: Bar
{
     Public int SomeOtherVal{get;set;}
}

[DataContract]
[Serializable]
public class Bar2: Bar
{
     Public int YetAnotherOtherVal{get;set;}
}

我有第二个 Foo 类型的 DataContract,它有一个公共属性 List。例如

[DataContract]
[Serializable]
public class Foo
{
    Public List<Bar> Bars {get;set;}

}

我有一个 ServiceContract(接口),它有 2 种支持 SOAP 和 JSON 的方法。

[ServiceContract]
public interface IFooWorld
{
    [OperationContract]
    [WebInvoke(RequestFormat = WebMessageFormat.Json, ResponseFormat =    WebMessageFormat.Json)]
    [ServiceKnownType(typeof(Bar1))]
    [ServiceKnownType(typeof(Bar2))]
    Foo GetFoo();

    [OperationContract]
    [WebInvoke(RequestFormat = WebMessageFormat.Json, ResponseFormat =  WebMessageFormat.Json)]
    [ServiceKnownType(typeof(Bar1))]
    [ServiceKnownType(typeof(Bar2))]
    void SetFoo(Foo foo);
}

使用 SOAPUI,我可以确认 GetFoo 正在返回 Bars 的多态数组,其中包含数组中的 Bar1 和 Bar2 对象。

使用日志记录,我了解到,当我在 Foo.Bar 中使用 Bar1 和 Bar2 对象的混合数组调用 SetFoo 时,Bar 本身不是空的,而是空的。

我在 SOAP 中有各种样式的 Bar 参数

样式 1 - 这导致入站 Bar 数组被分配但为空

<ns:Bars>
    <ns:Bar1>...
    </ns:Bar1>
    <ns:Bar2>...
    </ns:Bar2>
</ns:Bars>

样式 2 - 这导致入站 Bar 数组具有 Bar 类型的项目,而不是 Bar1 和 Bar2

<ns:Bars>
    <ns:Bar i:type="Bar1">...
    </ns:Bar>
    <ns:Bar i:type="Bar2">...
    </ns:Bar>
</ns:Bars>

这些都不起作用。关于如何在 DataContract 中为 SOAP 和 JSON 中的入站调用支持这种多态性的任何建议?

4

1 回答 1

1

您缺少[DataMember]数据类的每个属性。DataContractSerialiser 是一个选择加入序列化程序,这意味着您需要选择加入它才能对属性执行任何操作。

从而改变你的课程。

    [DataContract]
    [Serializable]
    [KnownType(typeof(Bar1))]
    [KnownType(typeof(Bar2))]
    public class Bar
    {
        [DataMember]
        Public int SomeVal{get;set;}
    }

    [DataContract]
    [Serializable]
    public class Bar1: Bar
    {
        [DataMember]
        Public int SomeOtherVal{get;set;}
    }

    [DataContract]
    [Serializable]
    public class Bar2: Bar
    {
        [DataMember]
        Public int YetAnotherOtherVal{get;set;}
    }


    I have a second DataContract of Type Foo, which has a public property, List<Bar>.
    e.g.
    [DataContract]
    [Serializable]
    public class Foo
    {
        [DataMember]
        Public List<Bar> Bars {get;set;}

    }
于 2013-05-08T08:49:46.597 回答