为什么 WCF 将请求/响应类型包装在另一个 XML 元素中,以及如何防止这种情况发生?
我有一个简单的 echo 服务,其中定义了一个操作方法和一对请求/响应类型:
[ServiceContract(Name = "EchoService",
Namespace = "http://example.com/services",
SessionMode = SessionMode.NotAllowed)]
public interface IEchoService
{
[OperationContract(IsOneWay = false,
Action = "http://example.com/services/EchoService/Echo",
ReplyAction = "http://example.com/services/EchoService/EchoResponse")]
EchoResponse Echo(EchoRequest value);
}
数据类型:
[Serializable]
[DataContract(Namespace = "http://example.com/services/EchoService",
Name = "EchoRequest")]
public class EchoRequest
{
public EchoRequest() { }
public EchoRequest(String value)
{
Value = value;
}
[DataMember]
public String Value { get; set; }
}
[Serializable]
[DataContract(Namespace = "http://example.com/services/EchoService",
Name = "EchoResponse")]
public class EchoResponse
{
public EchoResponse() { }
public EchoResponse(String value)
{
Value = value;
}
[DataMember]
public String Value { get; set; }
}
在 EchoRequest 实例上调用 Message.CreateMessage() 会产生:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header />
<s:Body>
<EchoRequest xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://example.com/services/EchoService">
<Value>hello, world!</Value>
</EchoRequest>
</s:Body>
</s:Envelope>
...这正是我想要的。 但是,该服务似乎希望将消息正文进一步包装在另一个 XML 元素中,如下所示:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header />
<s:Body>
<Echo xmlns="http://example.com/services">
<EchoRequest xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://example.com/services/EchoService">
<Value>hello, world!</Value>
</EchoRequest>
</Echo>
</s:Body>
</s:Envelope>
更新: 感谢 Mark 的回复,我在请求/响应类型上探索了 MessageContract 而不是 DataContract。 这似乎更接近我想要的,但现在它太过分了,并且不期望外部类型元素“EchoRequest”。
这很令人困惑,因为不知何故 Message.CreateMessage 似乎总是能够生成正确的 XML,因此它显然使用了一些默认的序列化,我希望将服务配置为接受。 我只是误解了 Message.CreateMessage 的工作原理吗?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
IIRC、WCF 默认情况下使用“Wrapped”消息样式。 如果您希望能够控制消息的序列化方式,可以通过使用 MessageContractAttribute。 对于显式消息协定,您可以设置 IsWrapped 属性设置为
false
。在你的情况下,我认为 EchoRequest 和 EchoResponse 根本不应该是 DataContracts,而应该是 MessageContracts。 对我来说,它们看起来很像 MessageContracts。
IIRC, WCF by default uses the 'Wrapped' message style. If you want to be able to control how messages are serialized, you can define explicit messages by decorating with the MessageContractAttribute. With explicit message contracts, you can set the IsWrapped property to
false
.In your case I think that EchoRequest and EchoResponse shouldn't be DataContracts at all, but rather MessageContracts. They look a lot like MessageContracts to me.
我最终转而使用 消息合约,使用 TypedMessageConverter 我是通过 这个问题的答案。 这就是这里缺失的部分。
I eventually switched over to use Message Contracts using a TypedMessageConverter which I was introduced to via this question's answer. That was the missing piece here.