0

我刚刚从 nuget 更新了对新 ServiceStack 的引用(从 3.9.11 到版本 3.9.56),但我无法让我的肥皂客户端工作。所以我决定再次尝试 [github] ( https://github.com/ServiceStack/ServiceStack.Examples/tree/master/src/ServiceStack.Hello ) 上提供的 Hello World 解决方案,顺便说一下,它使用的是旧版本(3.9.32)。

我在和类上添加了[DataContract]属性,然后尝试通过向我的 localhost soap12 端点添加服务引用来构建 C# 控制台客户端(使用 VS2010 上的添加服务引用,也尝试了 2012 和 2013)。不幸的是,虽然我确实得到了,但我没有生成任何 DTO。这是为什么?我尝试使用旧版本的 ServiceStack 构建我的代码(使用and方法并且一切正常!是否有任何我不知道的重大更改?HelloHelloResponseOneWayClientSyncReplyClientIService<T>Execute

PS我还尝试针对nuget库重新编译整个ServiceStack.Examples项目,但它也失败了。我什至无法生成代理。请不要试图说服我为我的 DTO 使用共享程序集,因为这违背了拥有与语言无关的 Web 服务的目的!

4

2 回答 2

3

请不要试图说服我为我的 DTO 使用共享程序集,因为这违背了拥有与语言无关的 Web 服务的目的!

听起来不像是把事情做好的态度。不确定您认为服务的目的是什么,但它不是实现复杂的 WS-* 规范(已死),甚至不是安抚一些专有的代码生成代理工具,尤其是那些生成 RPC 方法签名耦合代码的工具-gen 类型来生成仅限于使用低效且臃肿的 SOAP 格式的代理客户端,这种格式提供了可以说是当今Web 服务实现中使用的最脆弱的技术组合

服务的目的实际上是……只是为了提供服务——封装一些功能并使其远程可用,以尽可能最容易访问、最宽容和可互操作的方式,理想情况下以最少的努力、摩擦和复杂性有效地进行。

不确定为什么您认为 SOAP 生成的代理是拥有与语言无关的 Web 服务的通行证?鉴于代码生成代理实现在企业中不流行的平台上通常很弱、不完整且已弃用。

WSDL 的全部目的是提供一些机器可读的规范,代码生成代理可以使用这些规范来生成类型化的服务客户端——这就是 WSDL(不是服务)的目的——提供一种手段来达到目的的工具(以提供与服务的连接)。但是在所有这些复杂性和闭源黑盒工具下,它仍然无法重新创建在服务器上开发和维护的干净 DTO 类型。但是您可以通过将 .dll(或源代码)复制到您的 .NET 客户端项目来避免所有这些人为机制和复杂性,从而为您提供与服务器 DTO 的对称奇偶校验,从而使您可以使用任何 ServiceStack 的通用 .NET 服务客户端提供以任何支持的格式(甚至是内置的 WCF/SOAP 客户端)重用相同 DTO 的能力,因为通用类型化客户端是可替代的。

WS-*/SOAP 已被弃用,因为它不必要地复杂,它建立在一个错误的前提之上,即要提供“可互操作的服务”,您需要抽象、明确和选择加入复杂性。反之亦然,您可以使用更简单的格式和简单的 URI 获得更好的互操作性、更少的努力和摩擦,这就是为什么今天的新 Web API 不支持 SOAP。

于 2013-08-14T09:02:11.250 回答
2

我终于解决了这个问题,所以我将在这里发布答案。尽管 github repo 上的所有示例都需要更新才能使用最新版本,但 ServiceStack 并没有看起来那么糟糕。所以重点:如果你想让你的类正确地产生代理类,你必须不仅用[DataContract]类级别的属性而且用[DataMember]属性级别的属性来装饰它们,即

[DataContract]
class User
{
    [DataMember]
    public String Name { get; set; }
}

当然,您还需要在[DataContract]属性上指定命名空间(为了与 Mono 兼容),或者您必须在 AssemblyInfo.cs 上添加几行,如此处所述

请注意!你所有的 DTO,包括请求类型和响应类型都应该在同一个命名空间中!此外,如果您仅将第一级类定义为请求类型(如我使用的用户示例),那么您将不会获得代理类!相反,所有公共成员都将成为方法参数。如果你有,通过组合,用户类中的另一个公共成员,即

[DataContract]
class User
{
    [DataMember]
    public String Name { get; set; }
    [DataMember]
    public MyClass MyMember { get; set; }
}

那么您将获得 MyClass 的代理,但不是 User。至于响应类型,最好阅读关于 SOAP 限制的 ServiceStack wiki

最后一点:我通常只对灵活性、简单性、寻找替代方案和使事情起作用有强烈的看法。我发现那些试图支持一种语言而不是另一种语言、一种体系结构而不是另一种、流行语/利基技术而不是标准方法的讨论是毫无意义的,使用让生活更轻松的工具而不是硬编码一切。因此,我认为对上述评论的讨论是这样的,我不想再继续了。

我很高兴像 ServiceStack 这样出色的工具继续提供大多数用户使用它的功能:多种选择。

于 2013-08-18T19:26:12.623 回答