在WCF中,数据契约类可以相互继承吗?

发布于 2024-07-13 08:20:22 字数 1886 浏览 9 评论 0原文

在 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 服务,请检查您是否已在指定地址启用元数据发布。 有关启用元数据发布的帮助,请参阅 MSDN 文档,网址为 http://go .microsoft.com/fwlink/?LinkId=65455.WS-Metadata Exchange 错误 URI:http:// localhost:8002/GISDataServices/mex 元数据包含无法解析的引用: '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:请参阅下面我的回答。

In a WCF service, I have two classes with the [DataContract] attribute. One of these classes has an "is-a" relationship with the other - so class B can inherit from class A. However, when I configure inheritance between these two classes, both denoted with a [DataContract] attribute, the metadata fails to load when testing the services.

Is this possible in WCF? Am I missing another attribute?

[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; }
}

NOTE: The custom types are also defined using data contracts.

UPDATE: Below is the error:

Error: Cannot obtain Metadata from http://localhost:8002/GISDataServices/mex If this is a Windows (R) Communication Foundation service to which you have access, please check that you have enabled metadata publishing at the specified address. For help enabling metadata publishing, please refer to the MSDN documentation at http://go.microsoft.com/fwlink/?LinkId=65455.WS-Metadata Exchange Error URI: http://localhost:8002/GISDataServices/mex Metadata contains a reference that cannot be resolved: 'http://localhost:8002/GISDataServices/mex'.Receivera:InternalServiceFaultThe server was unable to process the request due to an internal error. For more information about the error, either turn on IncludeExceptionDetailInFaults (either from ServiceBehaviorAttribute or from the <serviceDebug> configuration behavior) on the server in order to send the exception information back to the client, or turn on tracing as per the Microsoft .NET Framework 3.0 SDK documentation and inspect the server trace logs.HTTP GET Error URI: http://localhost:8002/GISDataServices/mex There was an error downloading 'http://localhost:8002/GISDataServices/mex'. The request failed with HTTP status 400: Bad Request.

UPDATE 2: See my answer below.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

梦与时光遇 2024-07-20 08:20:22

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

Yes, but you need to decorate the base class with the [KnownTypeAttribute] constructing it with the derived class's type. For instance:

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

[DataContract]
public class B : A
{
   [DataMember]
   public string OtherValue { get; set; }
}
等待我真够勒 2024-07-20 08:20:22

好吧,我明白了这个问题。 答案是……我是个白痴。 这与继承无关。 在基类中,我有一个没有“set”属性子句的数据契约成员 - 只有一个“get”。 哎呀!!! 添加一个“set”子句使它像一个魅力一样发挥作用。

对困惑感到抱歉。

Okay, I figured out the question. The answer is...I'm an idiot. It had nothing to do with inheritance. In the base class, I had a data contract member without a 'set' property clause - only a 'get'. Doh!!! Putting in a 'set' clause made it work like a charm.

Sorry for the confusion.

心凉怎暖 2024-07-20 08:20:22

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

Based on this test it should work fine. Do both classes have Default Constructors? Are you using Auto-Properties. Note, In this basic sample the Attributes aren't required. Also, as David Morton mentioned you depending on which element you're returning you may need the KnownType attribute, I'm not 100% but the known type might have to go on the operation contract.

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();
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文