是否可以在 SOAP Web 服务中创建只读元素?
Posted
技术标签:
【中文标题】是否可以在 SOAP Web 服务中创建只读元素?【英文标题】:Is it possible to create read only elements in SOAP web services? 【发布时间】:2009-05-27 13:24:34 【问题描述】:我有一个定义了只读属性的类。在我的代码中,我将其定义为仅具有 getter 的属性。
我希望能够通过 Web 服务来回发送此对象。当我在服务中调用“Get”方法时,它将在服务端填充一个值。定义此属性后,我不希望 Web 服务的使用者能够设置/更改此属性。
当我将此 Web 服务的引用添加到项目时,该对象的属性序列化了几种不同的方式,具体取决于我尝试在服务端定义对象的方式:
内部设置器:在 WSDL 中创建属性。 Visual Studio 会为此属性生成一个具有 getter 和 setter 的类。 no setter:不在 WSDL 中创建属性。那么 Visual Studio 显然根本没有定义这个属性。 只读公共成员变量 - 不在 WSDL 中创建属性。同样,Visual Studio 不会对这个属性做任何事情,因为它不知道。允许 Web 服务的使用者为此属性设置值不会造成任何损害。如果设置了该值,则在 Web 服务端将被忽略。如果消费者不能更改/设置属性开始,我会更喜欢。
有没有办法将属性定义为只读?现在我们正在使用 C#/.NET 2.0 作为 Web 服务,并且(至少现在)我们可以控制该服务的所有消费者,所以如果需要我可以尝试更改配置,但我更喜欢只更改Web 服务上的东西,而不是消费者。
【问题讨论】:
【参考方案1】:我可能是错的,但我认为这里的问题是序列化是如何工作的——为了反序列化一个对象,序列化程序创建一个空对象,然后设置这个对象的所有属性——这就是为什么你需要一个属性的设置器被包含在序列化中。客户端代码与反序列化器具有相同的对象“接口”。
【讨论】:
我就是这么想的。我希望有一些方法可以解决这个问题。【参考方案2】:注意,我是一名 Java 人,所以我的答案的第一部分侧重于 C# 中可能发生的事情。
首先,使用 Java 中的自定义序列化程序,您几乎可以做任何您想做的事情,包括使用反射直接设置受保护或私有字段的值,只要安全管理器不阻止此活动。我不知道 C# 中是否有用于安全管理器、字段访问和自定义序列化程序的类似组件,但我怀疑有。
其次,我认为您将 Web 服务和将 Web 服务接口视为应用程序的一部分的方式存在根本差异。您可以右键单击从现有代码生成 Web 服务接口 - 称为“代码优先”。有很多关于为什么首先使用 WSDL 是首选方法的文章。 This 一个人总结得很好,但我也建议阅读其他人。当您考虑在 Web 服务的客户端和服务器端之间共享代码库并维护对象结构和可访问性时,一旦您将 API 作为 Web 服务发布并且无法控制所有的消费者。 WSDL 和 XSD 用作 Web 服务 API 的通用描述,并且您的服务器和客户端可以使用不同的数据绑定配置、对象类或语言来实现。您应该将您的 Web 服务接口和传入和传出它的 XML 视为描述交换的语义,但不一定是数据的语法(您的类结构),一旦它在您的客户端中被内部化(反序列化)或服务器。
此外,建议将与传输相关的结构与内部业务逻辑结构分离,以免您发现自己不得不同时重构服务器实现、Web 服务 API 以及您(和其他人的)客户端实现.
【讨论】:
我想过使用自定义序列化程序,然后我想到了你提到的第二点。我可以在服务端非常轻松地序列化数据,但是一旦将其发送到客户端,他们将需要自己的序列化程序来读取发送的 XML。这似乎是一种混乱的做事方式。【参考方案3】:据我所知,.NET 2.0 中没有内置的方法可以做到这一点。在我想序列化只读属性的情况下,我实现了IXmlSerializable
接口,以便我可以控制ReadXml()
和WriteXml()
方法。
在更高版本的 .NET 框架中,您可以通过在支持字段上设置属性来序列化只读属性。
【讨论】:
以上是关于是否可以在 SOAP Web 服务中创建只读元素?的主要内容,如果未能解决你的问题,请参考以下文章
Spring Boot Soap Web 服务(Java)——代码优先?
Spring Boot Soap Web-Service(Java) - 代码优先?