【问题标题】:In WCF, can data contract classes inherit from one another?在 WCF 中,数据协定类可以相互继承吗?
【发布时间】:2010-10-05 10:29:12
【问题描述】:

在 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 或来自 配置行为)以便将异常信息发送回客户端,或者根据 Microsoft .NET Framework 打开跟踪3.0 SDK 文档并检查服务器跟踪日志。HTTP GET 错误 URI:http://localhost:8002/GISDataServices/mex 下载“http://localhost:8002/GISDataServices/mex”时出错。请求失败,HTTP 状态 400:错误请求。

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

【问题讨论】:

    标签: .net wcf contract


    【解决方案1】:

    是的,但是您需要使用 [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; }
    }
    

    【讨论】:

    • 这似乎不起作用。加载元数据时仍然出现错误。
    • 错误已发布。我正在阅读我的“Programming WCF Services”一书中的 KnownType 内容。一切看起来都正确……很奇怪。
    • 如何通过接口定义参数?我应该使用基类还是子类。理想情况下,我会使用子类 - 可以吗?
    • 顺便说一句,这些类型将从服务方法调用(不是输入)返回。
    • 这是互操作性吗?如果对方对继承一无所知会怎样?
    【解决方案2】:

    根据这个测试,它应该可以正常工作。这两个类都有默认构造函数吗?您是否使用自动属性。注意,在这个基本示例中,属性不是必需的。此外,正如 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();
    }
    

    【讨论】:

    • 我正在使用自动属性,但是当我删除继承结构时,它们可以正常工作。
    • 两个类都不使用显式构造函数。
    • 你能用问题继承结构更新你的帖子吗?
    • 您的服务 A 或 B 或两者的返回类型是什么?
    • 它可以根据调用的服务方法返回两者。
    【解决方案3】:

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

    很抱歉给您带来了困惑。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-07-01
      • 1970-01-01
      • 2019-12-27
      • 1970-01-01
      • 2013-05-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多