【问题标题】:Can I expose a data member in a WCF ServiceContract?我可以在 WCF ServiceContract 中公开数据成员吗?
【发布时间】:2023-03-19 19:47:02
【问题描述】:

在 WCF 服务中,是否可以在 ServiceContract 定义中包含数据成员?做这样的事情:

namespace My.Service.Contracts
{
    [ServiceContract]
    public interface IMyService
    {
        [OperationContract]
        ResultObject[] Search(SearchParams searchParams);

        [DataMember]
        MyCustomClass MyDataMember { get; }
    }
}

我可以从 ServiceContract 中公开MyDataMember 吗?场景将如下所示:以下实现服务合同的类具有我想使用公共字段/属性公开的成员数据。看起来像这样的东西: 我正在尝试在实现服务合同的类中公开字段/属性。例如:

public class MyService : IMyService
{
    private MyCustomClass _datafield;

    ResultObject[] Search(SearchParams searchParams){
        //Do the search
    }

    MyCustomClass MyDataMember {
      get: { return _dataField; }
    }
}

【问题讨论】:

  • 你想在这里实现什么?您必须通过 [OperationContract] 调用返回数据并通过其他调用将数据传回。
  • 编辑了问题,@ChrisF

标签: c# .net wcf datacontract servicecontract


【解决方案1】:

是否可以在 ServiceContract 定义中包含数据成员?

虽然编译器很乐意让您将带有[DataMember] 修饰的属性“添加”到服务接口,但任何 WCF 客户端都不会看到该属性。

所以如果你的服务接口被定义为:

[ServiceContract]
public interface IMyService
{
    [OperationContract]
    ResultObject[] Search(SearchParams searchParams);

    [DataMember]
    MyCustomClass MyDataMember { get; }
}

...假设您通过添加服务参考生成客户端代理,您将看不到MyDataMember

请注意,在添加服务引用时,您也不会看到任何属性。

向服务接口添加属性没有意义,添加[DataMember] 也没有意义。您将[DataMember] 添加到以[DataContract] 装饰并在您的服务接口中引用的类中。

MSDN 对数据合同有这样的说法:

数据契约是服务和客户端之间的正式协议,它抽象地描述了要交换的数据。也就是说,为了进行通信,客户端和服务不必共享相同的类型,只需相同的数据契约。数据契约为每个参数或返回类型精确定义了哪些数据被序列化(转换为 XML)以进行交换。 - Golly, tell me more...

WCF 本质上是关于调用方法的(实际上它更多的是关于创建一个统一的通信 API,为您提供 RPC 作为免费的牛排刀集)。方法通常通过向服务发送 SOAP 消息来调用(尽管它也可以是 REST)。消息具有用[DataMember] 修饰的属性,以指示该属性应该被序列化并包含在消息流中。还有[MessageContract],但我们不会去那里。

无论如何,您不会访问 WCF 服务上的“属性”,而是调用方法。

告诉我更多

要详细了解 WCF 的史诗性,何不查看下面的链接。底部还有一个相当不错的例子:

【讨论】:

  • 谢谢@MickyD。你的回答很有道理。编译器/IDE 的容错性让我感到困惑。这是否意味着我必须更改我的类设计,以将我想从 WCF 客户端访问的所有数据与实现服务契约的类完全分开?
  • @Bahaa 是的。将您的数据定义放在[DataContract] 类中。您已经有一个MyCustomClass,所以只需将[DataContract] 添加到它,并将[DataMember] 添加到每个属性。然后在你的服务接口中定义方法,比如MyCustomClass Get (int i)void DoSomething(MyCustomClass foo)
  • 感谢您的全面回答
【解决方案2】:

你不能继承DataMember属性。

定义是on msdn

[AttributeUsageAttribute(AttributeTargets.Property|AttributeTargets.Field, Inherited = false,AllowMultiple = false)]
public sealed class DataMemberAttribute : Attribute

虽然这在技术上并不限制您使用DataMember 属性来装饰接口成员,但是您也必须使用此属性来装饰实现类成员。

这不是预期的使用方式。

【讨论】:

    猜你喜欢
    • 2011-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多