i having issue consuming legacy webservice using wcf. resolved 1 issue dealing fact webservice using different sign , encryption keys. when make webservice call version miss match response. when @ envelope produced in wse notice version of soap different 1 produced wcf.
my wse envelope header looks this:
<soap:envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" xmlns:xsd="http://www.w3.org/2001/xmlschema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
whereas wcf enveloped header
<s:envelope xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:s="http://www.w3.org/2003/05/soap-envelope">
i added code try , change namespace , prefix of soap envelope.
endpointaddress serviceendpoint = new endpointaddress(new uri("http://mylegacywebservice.com")); custombinding binding = new custombinding(); asymmetricsecuritybindingelement securitybe = securitybindingelement.createmutualcertificateduplexbindingelement( messagesecurityversion.wssecurity10wstrust13wssecureconversation13wssecuritypolicy12basicsecurityprofile10); // add custom identityverifier because service uses 2 certificates // (one signing , 1 encryption) , endpoint identity // contains 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);
below 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; (int = 0; < 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 xmlelement; if (childelement != null) { xmlelement newchildelement = changeprefixes(doc, childelement); if (newchildelement != childelement) { toreplace.add(new keyvaluepair<xmlnode, xmlnode>(childelement, newchildelement)); } } } if (toreplace.count > 0) { (int = 0; < toreplace.count; i++) { element.insertafter(toreplace[i].value, toreplace[i].key); element.removechild(toreplace[i].key); } } return element; }
}
below 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 { { 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 custombinding; if (custom == null) { custom = new custombinding(originalbinding); } (int = 0; < custom.elements.count; i++) { if (custom.elements[i] 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; }
Comments
Post a Comment