我可以为WCF ServiceContract公开数据成员吗?

3
在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
修改了问题,@ChrisF - Bahaa
2个回答

7

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

尽管编译器可以很轻松地让您“添加”一个使用[DataMember]修饰的属性到服务接口中,但任何WCF客户端都无法看到该属性。

因此,如果您的服务接口被定义为:

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

    [DataMember]
    MyCustomClass MyDataMember { get; }
}

假设您是通过添加服务引用来生成客户端代理,那么您将看不到MyDataMember的任何提及:

enter image description here

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

enter image description here

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

MSDN对数据合同有这样的描述:

数据合同是服务和客户端之间的正式协议,抽象地描述要交换的数据。也就是说,为了通信,客户端和服务不必共享相同的类型,只需共享相同的数据合同。数据合同精确地定义了每个参数或返回类型将序列化(转换为XML)以进行交换的数据。 - 告诉我更多...

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

总之,在WCF服务上不会访问“属性”,而是调用方法。

告诉我更多

要了解更多关于WCF的史诗般的内容,为什么不查看下面的链接呢?底部甚至有一个相当不错的示例:


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

1

你无法继承 DataMember 属性。

定义在 msdn 上

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

尽管这并不严格要求您使用 DataMember 属性来装饰接口成员,但您也必须使用该属性来装饰实现类成员。

这并非预期的使用方式。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接