ServiceStack hello world示例不生成soap代理

时间:2013-08-14 06:18:19

标签: c# web-services servicestack

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

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

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

2 个答案:

答案 0 :(得分:3)

  

请不要试图说服我为我的DTO使用共享程序集,因为这会破坏与语言无关的Web服务的目的!

听起来不像是一个完成任务的态度。不确定你认为服务的目的是什么,但它不是实现复杂的WS- *规范(已经死了),它甚至不能安抚一些专有的代码生成代理工具,特别是生成RPC方法签名耦合代码的工具-gen类型生成代理客户端,这些客户端仅限于使用低效且臃肿的SOAP格式,这种格式可以提供今天的most fragile combination of technologies used in web service implementations

服务的目的实际上......只是为了提供服务 - 封装一些功能并以最容易访问,容忍和可互操作的方式远程使用它,理想情况下以最少的努力,摩擦力和复杂性。

不确定为什么您认为SOAP生成的代理是拥有与语言无关的Web服务的门票?鉴于代码生成代理实现在企业内部不受欢迎的平台上通常很弱,不完整和被弃用。

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

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

答案 1 :(得分:2)

我终于解决了这个问题,所以我将在这里发布答案。虽然github repo上的所有示例都需要更新才能使用最新版本,但ServiceStack并没有像它看起来那样破碎。所以要点:如果你希望你的类正确地生成代理类,你不仅需要在类级别上使用[DataContract]属性来装饰它们,而且还要在属性级别使用[DataMember]来装饰它们,即< / p>

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

当然,您还需要在[DataContract]属性上指定命名空间(对于Mono兼容性),或者您必须按照here所述在AssemblyInfo.cs上添加几行。

但要注意!您的所有DTO(包括请求类型和响应类型)都应位于同一名称空间中!此外,如果您只将第一级类定义为请求类型(例如我使用的用户示例),那么您将获取代理类!相反,所有公共成员都将成为方法参数。但是,如果您通过撰写,在User类中有另一个公共成员,即

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

然后您将获得MyClass的代理,但不是用户。至于响应类型,请更好地阅读ServiceStack wiki on SOAP limitations

最后注意:我通常只对灵活性,简单性,寻找替代方案和使事情有效有强烈意见。我发现无意义的讨论试图支持一种语言而不是另一种语言,一种架构而不是另一种语言,一种关于标准方法的流行语/小众技术,使用的工具可以使生活更轻松,而不是硬编码。所以我在上面的评论中看到了这样的讨论,我希望不再继续。

我很高兴像ServiceStack这样的优秀工具继续提供大多数用户使用它的工具:各种替代方案。