给定运营合同,例如:
[OperationContract]
void Operation(string param1, string param2, int param3);
这可以重新设计为:
[MessageContract]
public class OperationRequest
{
[MessageBodyMember]
public string Param1 { get; set; }
[MessageBodyMember]
public string Param2 { get; set; }
[MessageBodyMember]
public int Param3 { get; set; }
}
[MessageContract]
public class OperationResponse
{
}
[OperationContract]
OperationResponse Operation(OperationRequest request);
我喜欢MessageContract的一件事是我对SOAP消息的格式有了更明确的控制。
同样,我可以编写几乎相同的代码,但使用DataContract:
[DataContract]
public class OperationRequest
{
[DataMember]
public string Param1 { get; set; }
[DataMember]
public string Param2 { get; set; }
[DataMember]
public int Param3 { get; set; }
}
[DataContract]
public class OperationResponse
{
}
[OperationContract]
OperationResponse Operation(OperationRequest request);
我喜欢DataContract的一件事是我可以定义IsRequired,Order和Name。
今天我预计唯一的消费者将是WCF客户端。但是,我想首先设计合同并尽可能地遵守SOA实践。我不希望WCF指示我的SOAP,WSDL和XSD,而是希望XML定义WCF层,但是使用WCF来生成它,以便不向WCF添加任何自定义消息处理。我想遵循最常见的SOA XML约定,我认为这些约定可能都是以小写字母开头的标签 - 我是对的吗?我希望尽可能地容忍版本。
总是创建像这样的请求和响应消息是明智的吗?这三种格式中的哪一种促进了最佳SOA实践?我是否应该更进一步定义DataContract和MessageContract,其中MessageContract只包含DataContract?或者,如果我真的暴露了一种新类型(即不要将消息类型创建为容器),我是否应该只使用DataContracts?
我知道的一系列问题,但是我试图找到它的核心,我不确定将问题分开提供足够的背景来得到我正在寻找的答案。
答案 0 :(得分:15)
最好不要在操作合同中包含多个参数,总是有一个包装所有必需参数的类型,从长远来看这将有所帮助。添加新的可选参数时,现有客户端不会中断。
我在一个业务集成团队工作,我们定期与其他公司(AT& T,Cox,Exxon ......)进行集成,并且从未见过只接受过一个参数的Web服务调用。
答案 1 :(得分:6)
XML
通常倾向于以驼峰为基础。 WSDL
和XML
架构对元素和属性使用camelCasing,例如,请查看syntax和schema。
为什么SOAP
的定义不同,我不知道,但它使用PascalCasing作为元素,使用camelCasing作为属性,请检查here。
类似地,大多数WS*
规范(可能全部)都使用PascalCasing作为元素和属性,请参阅here。 XML Schema与它为XML定义的类型的约定无关。
Thomas Erl在SOA
上撰写了许多重要的书籍,包括“面向服务的架构”。在章节 13 和 15 中,他提供了许多典型事务各部分的XML示例。它使用PascalCasing在XML Schema中定义类型和对象成员,它很好地匹配C#的常规模式,用于类和属性命名。因此WCF
默认值已经与标准非常接近。
关于实际的消息命名,一些约定使用camelCasing而其他约定使用PascalCasing,所以我的首选是匹配主要语言需求,WCF
情况下是PascalCasing。 WCF
默认值匹配应如何编写请求和响应消息的一些示例some examples here。
因此,唯一悬而未决的问题是关于使用OperationContract
,DataContract
和/或MessageContract
进行标准化的基本问题。
只有当你有一个复杂类型(用XSD
用语)才有意义时定义DataContract,我倾向于认为特里指出的YAGNI(你不需要它)是正确的选择,但是 Erl 似乎提出了一个更加流程密集的版本,所以我仍然不确定使用哪种方法作为我的默认选择(问题的主要部分)。
答案 2 :(得分:0)
我认为这实际上取决于场景。如果你只是交换简单的类型[即字符串],OperationContract当然可以接受。
当您想要修改消息格式时应使用MessageContract,并且当您想表达复杂类型(例如地址)时应使用DataContract。
答案 3 :(得分:0)
我说不要过于花哨地展望未来。 WCF已经非常适合SOA了。我说,一般来说,坚持使用默认值并注意耦合,直到你有特别需要做一些精心设计的事情。