为什么 WCF 将请求/响应类型包装在另一个 XML 元素中,以及如何防止这种情况发生?
-
13-09-2019 - |
题
我有一个简单的回显服务,其中定义了一个操作方法和一对请求/响应类型:
[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 的工作原理吗?
其他提示
IIRC,WCF默认使用“包裹”消息样式。如果您希望能够控制消息的序列化,你可以通过使用的 MessageContractAttribute 。有了明确的消息,合同,您可以设置 IsWrapped 一>属性false
。
在你的情况我认为和的EchoRequest不EchoResponse应该在所有DataContracts,而是MessageContracts。他们看起来很像MessageContracts给我。
不隶属于 StackOverflow