我遇到了类似的问题。我不确定这是否有用。
MSDN WCF 可扩展性
http://blogs.msdn.com/b/carlosfigueira/archive/2011/04/19/wcf-extensibility-message-inspectors.aspx
此处的设置是基于证书、Oracle 应用服务器 10g 和 .Net 来使用服务的。在尝试弄清楚请求和响应发生了什么时,使用 SOAPUi 非常有用。
我没有尝试修改代码以使用 basicHttpBinding,但我使用 WSHttpBinding 作为代码中配置的基础。然后用了
WSHttpBinding binding = new WSHttpBinding()
{
CloseTimeout = new TimeSpan(0, 1, 0),
OpenTimeout = new TimeSpan(0, 1, 0),
SendTimeout = new TimeSpan(0, 1, 0),
AllowCookies = false,
BypassProxyOnLocal = false,
HostNameComparisonMode = HostNameComparisonMode.StrongWildcard,
MaxBufferPoolSize = 524288,
MaxReceivedMessageSize = 65536,
MessageEncoding = WSMessageEncoding.Text,
UseDefaultWebProxy = false,
ReaderQuotas = new System.Xml.XmlDictionaryReaderQuotas()
{
MaxDepth = 32,
MaxArrayLength = 16384,
MaxBytesPerRead = 4096,
MaxNameTableCharCount = 16384,
MaxStringContentLength = 8192
}
};
binding.Security.Mode = SecurityMode.Transport;
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;
binding.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.None;
binding.Security.Transport.Realm = string.Empty;
binding.Security.Message.ClientCredentialType = MessageCredentialType.Certificate;
binding.Security.Message.EstablishSecurityContext = true;
binding.Security.Message.NegotiateServiceCredential = true;
CustomBinding customBinding = new CustomBinding();
BindingElementCollection collection = binding.CreateBindingElements();
循环遍历 TextMessageEncodingBindingElement 以将 Soap11 和 AddressingVersion 设置为 None。
foreach (BindingElement element in collection)
{
if (typeof(TextMessageEncodingBindingElement) == element.GetType())
{
TextMessageEncodingBindingElement item = element as TextMessageEncodingBindingElement;
if (null != item)
{
item.MessageVersion = MessageVersion.CreateVersion(EnvelopeVersion.Soap11, AddressingVersion.None);
customBinding.Elements.Add(item);
}
}
else
customBinding.Elements.Add(element);
}
我使用了 ChannelFactory 并为 Message Inspector 添加了 EndPoint Behavior。
此时我已经控制了请求,我可以添加适当的标头并修改 Action 上的 mustUnderstand。
使用 SOAPUi,我将 Message.ToString() 放入 SOAPUI 并测试了请求。一旦需要的项目被添加到请求中,然后确定 OAS 服务器没有回复所有必要的元素。使用消息检查器进行回复,我修改了消息以包含缺少的标题。我不记得在哪里找到了消息检查器的基本代码,但您需要修改代码才能正确使用它。
对于我的示例,这里有一些 sn-ps。
对于
中的转换消息
public object BeforeSendRequest
我需要修改标头,因此我使用 for 循环抓取 XElement 并添加 OASIS 标头并添加了 To 标头。
XNamespace xmlns = "http://schemas.xmlsoap.org/soap/envelope/";
XElement securityHeader = new XElement(
xmlns + "Security",
new XAttribute(xmlns + "wsse", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"),
new XAttribute(xmlns + "xmlns", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"),
new XAttribute(xmlns + "mustUnderstand", "0"));
element.Add(securityHeader);
我还必须修改 Action Header
else if (localName.Equals("Action", StringComparison.InvariantCultureIgnoreCase))
{
foreach (XAttribute a in element.Attributes())
{
if (a.Name.LocalName == "mustUnderstand")
a.Value = "0";
}
}
我的问题是服务没有回复操作标头
所以在
public void AfterReceiveReply
我调用了我的 TransformReply 返回类型 Message ,如下所示。您可能需要修改 string.Empty 的值,但这只是一个示例。
...
Message reply = Message.CreateMessage(message.Version, null, reader);
reply.Headers.Add(MessageHeader.CreateHeader("Action", string.Empty, string.Empty, false));
reply.Properties.CopyProperties(message.Properties);
...
我真的建议使用 SOUPUI 之类的工具来弄乱信封并查看回复。如果您使用 SSL,则需要创建一个 cacert 文件并将其放在首选项的 SSLSettings 中。