在WCF中传递复杂类型的标准化方法是什么?
-
03-07-2019 - |
题
我是WCF的新手,目前我正在开发TCP WCF服务,我不确定我是否理解正确传递参数,所以我建议你发表评论并给出标准化的方法。
为了清楚起见,我开发了一个用于测试目的的小型服务,该服务具有单一方法,并且依赖于暴露单个类的外部.Net dll。 服务合同代码
[ServiceContract]
public interface IMyService
{
[OperationContract]
int Test1(actionType at, calculationType ct, action a);
[OperationContract]
int Test2(DataSeries s);
}
其中 actionType
, calculationType
, action
是在外部dll中声明的枚举
和 DataSeries
是在dll中声明的类。
dll中 DataSeries
类的原始定义仅由 [Serializable]
标记,其成员上没有 [DataMember]
。
我在客户端和服务器端使用第三个dll,令我惊讶的是两个应用程序都工作正常而没有在DataSeries类上放置 [DataContract]
而不使用任何 [EnumMember]
在枚举中, [DataMember]
在类中。
那是怎么回事?
另一个实验:
从客户端删除第三方并按原样使用服务
我发现vs2008生成枚举和 DataSeries
类并用适当的属性标记它们?
喜欢
[System.CodeDom.Compiler.GeneratedCodeAttribute ("System.Runtime.Serialization", "3.0.0.0")]
[System.Runtime.Serialization.DataContractAttribute(Name="actionType", Namespace="http://schemas.datacontract.org/2004/07/DBInterface")]
public enum actionType : int {
[System.Runtime.Serialization.EnumMemberAttribute()]
All = 0,
[System.Runtime.Serialization.EnumMemberAttribute()]
Buy = 1,
[System.Runtime.Serialization.EnumMemberAttribute()]
Sell = 2,
}
解决方案
DataContract , DataMember 和 EnumMember 属性由 DataContractSerializer (通常 basicHttpBinding 或 wsHttpBinding )。如果您使用TCP绑定公开端点( netTcpBinding )仅需要 SerializableAttribute 。请注意,使用DataContractSerializer,您只能将SerializableAttribute添加到您的类中,它将自动序列化所有字段。
我建议您使用以下内容:如果您希望您的服务可以互操作,请使用basicHttpBinding并使用DataContract和DataMember属性标记您的类。如果您的客户端是.NET应用程序,请使用netTcpBinding并使用SerializableAttribute标记您的类。
您还可以阅读此发布以进行比较不同的绑定。
其他提示
但不使用DataContract或任何 属性,我找到了客户端 正常工作
是的,这是真的 - 如果你使用的数据类型没有用[DataContract]标记,WCF将尝试在它们上使用默认的SOAP序列化程序,并且只序列化所有公共属性(所有公共属性)。
它有效 - 但它可能不是你想要/期望的 - 所以我第二个darin的意见 - 只是总是在你的类型上使用显式[DataContract]属性。您对自己(或其他需要稍后维护代码的程序员)的意图越清晰越好。这些“魔术”技巧在幕后发生的事情往往会引起混乱 - 你最好不过分依赖它们
马克
所以对我来说,我使用[DataContract],并传入一个参数,并返回一个数据合约。
这提供了更大的灵活性,因为我可以使用新的可选属性将数据协定扩展到数据协定,而不会破坏任何现有客户端。
枚举我还创建了数据联系人;因为我可以这样做,扩展枚举而不会破坏任何东西,我可以控制命名空间。
[DataContract(Namespace = "http://namespace.mydomain.com/2009/05", Name = "ReferenceTypeData")]
public enum GenderEnum
{
[EnumMember()]
Unknown = 0,
[EnumMember()]
Male = 1,
[EnumMember()]
Female = 2
}
然后,您必须使用
标记服务合同[ServiceKnownType(typeof(GenderEnum))]
public interface IServiceContract
{
....
}