使用遗留Web服务的WCF
我在使用WCF使用遗留Web服务时遇到问题。 我解决了一个问题,即Web服务使用不同的签名和加密密钥。 但是当我调用webservice时,我得到了版本未匹配的响应。 当我查看WSE中生成的信封时,我注意到soap的版本与WCF生成的版本不同 我的WSE信封头如下所示:使用遗留Web服务的WCF,wcf,ws-security,legacy,wse,Wcf,Ws Security,Legacy,Wse,我在使用WCF使用遗留Web服务时遇到问题。 我解决了一个问题,即Web服务使用不同的签名和加密密钥。 但是当我调用webservice时,我得到了版本未匹配的响应。 当我查看WSE中生成的信封时,我注意到soap的版本与WCF生成的版本不同 我的WSE信封头如下所示: 而WCF封装了标题 <s:Envelope xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:s="http://www.w3.org/2003/05/soap-e
而WCF封装了标题
<s:Envelope xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:s="http://www.w3.org/2003/05/soap-envelope">
我添加了一些代码来尝试更改soap信封的名称空间和前缀
EndpointAddress serviceEndpoint =
new EndpointAddress(new Uri("http://mylegacywebservice.com"));
CustomBinding binding = new CustomBinding();
AsymmetricSecurityBindingElement securityBE =
SecurityBindingElement.CreateMutualCertificateDuplexBindingElement(
MessageSecurityVersion.WSSecurity10WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10);
// Add a custom IdentityVerifier because the service uses two certificates
// (one for signing and one for encryption) and an endpoint identity that
// contains a single identity claim.
securityBE.LocalClientSettings.IdentityVerifier = new MyIdentityVerifier();
binding.Elements.Add(securityBE);
CompositeDuplexBindingElement compositeDuplex =
new CompositeDuplexBindingElement();
compositeDuplex.ClientBaseAddress = new Uri("http://mylegacywebservice.com");
binding.Elements.Add(compositeDuplex);
binding.Elements.Add(new OneWayBindingElement());
binding.Elements.Add(new HttpTransportBindingElement());
Dictionary<string, string> namespaceToPrefixMapping = new Dictionary<string, string>
{
{ "http://schemas.xmlsoap.org/soap/envelope/", "soap" },
{ "http://schemas.xmlsoap.org/ws/2004/08/addressing", "wsa" },
};
binding = ReplacePrefixMessageEncodingBindingElement.ReplaceEncodingBindingElement(
new WSHttpBinding(SecurityMode.None),
namespaceToPrefixMapping);
endpointAddressServiceEndpoint=
新端点地址(新Uri(“http://mylegacywebservice.com"));
CustomBinding=新的CustomBinding();
AsymmetricSecurityBindingElement securityBE=
SecurityBindingElement.CreateMutualCertificatedPlexBindingElement(
MessageSecurityVersion.WSSecurity10WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10);
//添加自定义IdentityVerifier,因为服务使用两个证书
//(一个用于签名,一个用于加密)和端点标识
//包含单个标识声明。
securityBE.LocalClientSettings.IdentityVerifier=new MyIdentityVerifier();
binding.Elements.Add(securityBE);
CompositePlexBindingElement CompositePlex=
新的CompositedPlexBindingElement();
CompositePlex.ClientBaseAddress=新Uri(“http://mylegacywebservice.com");
binding.Elements.Add(compositedPlex);
添加(新的OneWayBindingElement());
添加(新的HttpTransportBindingElement());
Dictionary namespaceToPrefixMapping=新字典
{
{ "http://schemas.xmlsoap.org/soap/envelope/“,”soap“},
{ "http://schemas.xmlsoap.org/ws/2004/08/addressing“,“wsa”},
};
binding=ReplacePrefixMessageEncodingBindingElement.ReplaceEncodingBindingElement(
新的WSHttpBinding(SecurityMode.None),
namespaceToPrefixMapping);
以下是prefixreplace.cs:
public class PrefixReplacer
{
const string XmlnsNamespace = "http://www.w3.org/2000/xmlns/";
Dictionary<string, string> namespaceToNewPrefixMapping = new Dictionary<string, string>();
public void AddNamespace(string namespaceUri, string newPrefix)
{
this.namespaceToNewPrefixMapping.Add(namespaceUri, newPrefix);
}
public void ChangePrefixes(XmlDocument doc)
{
XmlElement element = doc.DocumentElement;
XmlElement newElement = ChangePrefixes(doc, element);
doc.LoadXml(newElement.OuterXml);
}
private XmlElement ChangePrefixes(XmlDocument doc, XmlElement element)
{
string newPrefix;
if (this.namespaceToNewPrefixMapping.TryGetValue(element.NamespaceURI, out newPrefix))
{
XmlElement newElement = doc.CreateElement(newPrefix, element.LocalName, element.NamespaceURI);
List<XmlNode> children = new List<XmlNode>(element.ChildNodes.Cast<XmlNode>());
List<XmlAttribute> attributes = new List<XmlAttribute>(element.Attributes.Cast<XmlAttribute>());
foreach (XmlNode child in children)
{
newElement.AppendChild(child);
}
foreach (XmlAttribute attr in attributes)
{
newElement.Attributes.Append(attr);
}
element = newElement;
}
List<XmlAttribute> newAttributes = new List<XmlAttribute>();
bool modified = false;
for (int i = 0; i < element.Attributes.Count; i++)
{
XmlAttribute attr = element.Attributes[i];
if (this.namespaceToNewPrefixMapping.TryGetValue(attr.NamespaceURI, out newPrefix))
{
XmlAttribute newAttr = doc.CreateAttribute(newPrefix, attr.LocalName, attr.NamespaceURI);
newAttr.Value = attr.Value;
newAttributes.Add(newAttr);
modified = true;
}
else if (attr.NamespaceURI == XmlnsNamespace && this.namespaceToNewPrefixMapping.TryGetValue(attr.Value, out newPrefix))
{
XmlAttribute newAttr;
if (newPrefix != "")
{
newAttr = doc.CreateAttribute("xmlns", newPrefix, XmlnsNamespace);
}
else
{
newAttr = doc.CreateAttribute("xmlns");
}
newAttr.Value = attr.Value;
newAttributes.Add(newAttr);
modified = true;
}
else
{
newAttributes.Add(attr);
}
}
if (modified)
{
element.Attributes.RemoveAll();
foreach (var attr in newAttributes)
{
element.Attributes.Append(attr);
}
}
List<KeyValuePair<XmlNode, XmlNode>> toReplace = new List<KeyValuePair<XmlNode, XmlNode>>();
foreach (XmlNode child in element.ChildNodes)
{
XmlElement childElement = child as XmlElement;
if (childElement != null)
{
XmlElement newChildElement = ChangePrefixes(doc, childElement);
if (newChildElement != childElement)
{
toReplace.Add(new KeyValuePair<XmlNode, XmlNode>(childElement, newChildElement));
}
}
}
if (toReplace.Count > 0)
{
for (int i = 0; i < toReplace.Count; i++)
{
element.InsertAfter(toReplace[i].Value, toReplace[i].Key);
element.RemoveChild(toReplace[i].Key);
}
}
return element;
}
公共类前缀替换器
{
常量字符串XmlnsNamespace=”http://www.w3.org/2000/xmlns/";
字典名称spacetonewprefixmapping=新字典();
public void AddNamespace(字符串namespaceUri,字符串newPrefix)
{
this.namespaceToNewPrefixMapping.Add(namespaceUri,newPrefix);
}
公共作废更改前缀(XmlDocument文档)
{
XmlElement=doc.DocumentElement;
xmlement newElement=更改前缀(doc,element);
doc.LoadXml(newElement.OuterXml);
}
私有XmlElement更改前缀(XmlDocument文档,XmlElement)
{
字符串前缀;
if(this.namespaceToNewPrefixMapping.TryGetValue(element.NamespaceURI,out newPrefix))
{
xmlement newElement=doc.CreateElement(newPrefix,element.LocalName,element.NamespaceURI);
List children=新列表(element.ChildNodes.Cast());
列表属性=新列表(element.attributes.Cast());
foreach(子节点中的XmlNode子节点)
{
newElement.AppendChild(child);
}
foreach(属性中的xmltattribute attr)
{
newElement.Attributes.Append(attr);
}
元素=新元素;
}
List newAttributes=newlist();
bool-modified=false;
对于(int i=0;i0)
{
for(int i=0;i
}
以下是ReplacePrefixMessageEncodingBindingElement:
public class ReplacePrefixMessageEncodingBindingElement : MessageEncodingBindingElement
{
MessageEncodingBindingElement inner;
Dictionary<string, string> namespaceToPrefixMapping = new Dictionary<string, string>();
public ReplacePrefixMessageEncodingBindingElement(MessageEncodingBindingElement inner)
{
this.inner = inner;
}
private ReplacePrefixMessageEncodingBindingElement(ReplacePrefixMessageEncodingBindingElement other)
{
this.inner = other.inner;
this.namespaceToPrefixMapping = new Dictionary<string, string>(other.namespaceToPrefixMapping);
}
public void AddNamespaceMapping(string namespaceUri, string newPrefix)
{
this.namespaceToPrefixMapping.Add(namespaceUri, newPrefix);
}
public override MessageEncoderFactory CreateMessageEncoderFactory()
{
return new ReplacePrefixMessageEncoderFactory(this.inner.CreateMessageEncoderFactory(), this.namespaceToPrefixMapping);
}
public override MessageVersion MessageVersion
{
get { return this.inner.MessageVersion; }
set { this.inner.MessageVersion = value; }
}
public override BindingElement Clone()
{
return new ReplacePrefixMessageEncodingBindingElement(this);
}
public override IChannelListener<TChannel> BuildChannelListener<TChannel>(BindingContext context)
{
context.BindingParameters.Add(this);
return context.BuildInnerChannelListener<TChannel>();
}
public override bool CanBuildChannelListener<TChannel>(BindingContext context)
{
return context.CanBuildInnerChannelListener<TChannel>();
}
public static CustomBinding ReplaceEncodingBindingElement(Binding originalBinding, Dictionary<string, string> namespaceToPrefixMapping)
{
CustomBinding custom = originalBinding as CustomBinding;
if (custom == null)
{
custom = new CustomBinding(originalBinding);
}
for (int i = 0; i < custom.Elements.Count; i++)
{
if (custom.Elements[i] is MessageEncodingBindingElement)
{
ReplacePrefixMessageEncodingBindingElement element = new ReplacePrefixMessageEncodingBindingElement((MessageEncodingBindingElement)custom.Elements[i]);
foreach (var mapping in namespaceToPrefixMapping)
{
element.AddNamespaceMapping(mapping.Key, mapping.Value);
}
custom.Elements[i] = element;
break;
}
}
return custom;
}
public类ReplacePrefixMessageEncodingBindingElement:MessageEncodingBindingElement
{
MessageEncodingBindingElement内部;
Dictionary namespaceToPrefixMapping=new Dictionary();
public ReplacePrefixMessageEncodingBindingElement(MessageEncodingBindingElement内部)
{
this.inner=内部;
}
专用ReplacePrefixMessageEncodingBindingElement(ReplacePrefixMessageEncodingBindingElement其他)
{
this.inner=other.inner;
this.namespaceToPrefixMapping=new D