设计SOA WCF Web服务时的最佳实践是什么?

时间:2009-01-24 19:48:11

标签: c# wcf web-services datacontract

给定运营合同,例如:

[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?

我知道的一系列问题,但是我试图找到它的核心,我不确定将问题分开提供足够的背景来得到我正在寻找的答案。

4 个答案:

答案 0 :(得分:15)

最好不要在操作合同中包含多个参数,总是有一个包装所有必需参数的类型,从长远来看这将有所帮助。添加新的可选参数时,现有客户端不会中断。

我在一个业务集成团队工作,我们定期与其他公司(AT& T,Cox,Exxon ......)进行集成,并且从未见过只接受过一个参数的Web服务调用。

答案 1 :(得分:6)

XML通常倾向于以驼峰为基础。 WSDLXML架构对元素和属性使用camelCasing,例如,请查看syntaxschema

为什么SOAP的定义不同,我不知道,但它使用PascalCasing作为元素,使用camelCasing作为属性,请检查here

类似地,大多数WS*规范(可能全部)都使用PascalCasing作为元素和属性,请参阅here。 XML Schema与它为XML定义的类型的约定无关。

Thomas ErlSOA上撰写了许多重要的书籍,包括“面向服务的架构”。在章节 13 15 中,他提供了许多典型事务各部分的XML示例。它使用PascalCasing在XML Schema中定义类型和对象成员,它很好地匹配C#的常规模式,用于类和属性命名。因此WCF默认值已经与标准非常接近。

关于实际的消息命名,一些约定使用camelCasing而其他约定使用PascalCasing,所以我的首选是匹配主要语言需求,WCF情况下是PascalCasing。 WCF默认值匹配应如何编写请求和响应消息的一些示例some examples here

因此,唯一悬而未决的问题是关于使用OperationContractDataContract和/或MessageContract进行标准化的基本问题。

只有当你有一个复杂类型(用XSD用语)才有意义时定义DataContract,我倾向于认为特里指出的YAGNI(你不需要它)是正确的选择,但是 Erl 似乎提出了一个更加流程密集的版本,所以我仍然不确定使用哪种方法作为我的默认选择(问题的主要部分)。

答案 2 :(得分:0)

我认为这实际上取决于场景。如果你只是交换简单的类型[即字符串],OperationContract当然可以接受。

当您想要修改消息格式时应使用MessageContract,并且当您想表达复杂类型(例如地址)时应使用DataContract。

答案 3 :(得分:0)

在这里想到了{p> YAGNI

我说不要过于花哨地展望未来。 WCF已经非常适合SOA了。我说,一般来说,坚持使用默认值并注意耦合,直到你有特别需要做一些精心设计的事情。