24

在 WCF 服务中,我有两个具有 [DataContract] 属性的类。其中一个类与另一个类具有“is-a”关系 - 因此类 B 可以从类 A 继承。但是,当我在这两个类之间配置继承时,都用 [DataContract] 属性表示,元数据无法加载在测试服务时。

这在 WCF 中可能吗?我是否缺少另一个属性?

[DataContract]
public class A
{        
    [DataMember]
    public MyCustomType AValue1{ get; set; }

    [DataMember]
    public MyCustomType AValue2 { get; set; }
}

[DataContract]
public class B: A
{       
   [DataMember]
   public double BValue1{ get; set; }

   [DataMember]
   public double BValue2 { get; set; }
}

注意:自定义类型也是使用数据协定定义的。

更新:以下是错误:

错误:无法从http://localhost:8002/GISDataServices/mex获取元数据如果这是您有权访问的 Windows (R) Communication Foundation 服务,请检查您是否已在指定地址启用元数据发布。有关启用元数据发布的帮助,请参阅位于http://go.microsoft.com/fwlink/?LinkId=65455.WS-Metadata Exchange 错误 URI:http://localhost:8002/GISDataServices/mex的 MSDN 文档 元数据包含无法解析的引用:' http://localhost:8002/GISDataServices/mex '。 Receivera:InternalServiceFault由于内部错误,服务器无法处理请求。有关错误的详细信息,请在服务器上打开 IncludeExceptionDetailInFaults(来自 ServiceBehaviorAttribute 或来自 <serviceDebug> 配置行为)以便将异常信息发送回客户端,或者根据 Microsoft .NET Framework 打开跟踪3.0 SDK 文档并检查服务器跟踪日志。HTTP GET 错误 URI:http://localhost:8002/GISDataServices/mex 下载“ http://localhost:8002/GISDataServices/mex ”时出错。请求失败,HTTP 状态为 400:错误请求。

更新 2:请参阅下面的答案。

4

3 回答 3

39

是的,但是您需要使用 [KnownTypeAttribute] 来装饰基类,并使用派生类的类型构造它。例如:

[DataContract]
[KnownType(typeof(B))]
public class A
{
   [DataMember]
   public string Value { get; set; }
}

[DataContract]
public class B : A
{
   [DataMember]
   public string OtherValue { get; set; }
}
于 2009-02-04T15:26:44.827 回答
7

好的,我想通了这个问题。答案是……我是个白痴。它与继承无关。在基类中,我有一个没有“set”属性条款的数据合同成员——只有一个“get”。啊!!!放入“设置”条款使其像魅力一样工作。

对困惑感到抱歉。

于 2009-02-04T16:23:13.793 回答
1

基于此测试,它应该可以正常工作。这两个类都有默认构造函数吗?您是否使用自动属性。注意,在这个基本示例中,属性不是必需的。此外,正如 David Morton 提到的,根据您要返回的元素,您可能需要 KnownType 属性,我不是 100%,但已知类型可能必须遵守操作合同。

class Program
{
    static void Main(string[] args)
    {
        var serializer = new DataContractSerializer(typeof(Employee));

        var employee = new Employee() { Name="Joe", Salary=100000  };
        using (var ms = new MemoryStream())
        {
            serializer.WriteObject(ms, employee);

            ms.Position = 0;

            var newEmployee = serializer.ReadObject(ms) as Employee;
        }

        Console.ReadKey();

    }
}

[DataContract]
public class Employee : Person
{
    [DataMember]
    public decimal Salary { get; set; }
}

[DataContract]
public class Person
{
    [DataMember]
    public string Name { get; set; }
}

[ServiceContract]
interface IEmployeeService
{
    [OperationContract]
    Person GetPerson();

    [OperationContract]
    Employee GetEmployee();

    [OperationContract]
    [KnownType(typeof(Employee))]
    Person GetEmployeeAsPerson();
}
于 2009-02-04T15:29:43.603 回答