Adding a custom SOAP header using c# - c#

I have created a proxy class in c# using Wsdl.exe from the WSDL structure.
I need to serialize the proxy class and send to an HttpWebRequest.
This is the code I used to serialize the class
using (System.IO.Stream soapStream = new System.IO.FileStream(#"C:\SoapFormat.xml", System.IO.FileMode.OpenOrCreate))
{
System.Xml.Serialization.SoapReflectionImporter soapRefImp = new System.Xml.Serialization.SoapReflectionImporter();
System.Xml.Serialization.XmlTypeMapping xmlTypeMapping = soapRefImp.ImportTypeMapping(typeof(clsPerson));
System.Xml.Serialization.XmlSerializer xmlSerializer =
new System.Xml.Serialization.XmlSerializer(xmlTypeMapping);
xmlSerializer.Serialize(soapStream, p);
}
I am getting the xml as
<?xml version="1.0"?>
<clsPerson xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" id="id1">
<FirstName xsi:type="xsd:string">Jeff</FirstName>
<MI xsi:type="xsd:string">A</MI>
<LastName xsi:type="xsd:string">Price</LastName>
</clsPerson>
I need to add soap envelope. how can i add in c#.
My output should be like this
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<clsPerson xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" id="id1">
<FirstName xsi:type="xsd:string">Jeff</FirstName>
<MI xsi:type="xsd:string">A</MI>
<LastName xsi:type="xsd:string">Price</LastName>
</clsPerson>
</soapenv:Body>
</soapenv:Envelope>
Do u need to create a string builder and add the soap envelope as string.
then insert the xml into that string.
for eg
string s= "<body>"+ xml + "</body">
Any other option in c# to create soap envelope?
I need to send this soapenvelope to a webservice as httprequest.
Any helps appreciated.
this requires webservice not wcf.
thanks
supriya

Related

How change namespace and prefix in WCF

My customer wants to a web service for integration. They send me the documentation and I created a WCF Service with methods.
But there are namespaces and prefixs problem. I didn't find any solution and I didn't find any suggest. For example there is a different tag (
Customer will send request like this:
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:ws="http://ws.common.haciosman.com">
<soapenv:Header />
<soap:Body>
<ws:getSystemStatus/>
</soap:Body>
</soap:Envelope>
Customer wants to response like that:
<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
<soapenv:Header/>
<soapenv:Body>
<ns:getSystemStatusResponse xmlns:ns="http://ws.common.haciosman.com">
<ns:return xsi:type="ax21:OutputMessage" xmlns:ax21="http://ws.common.haciosman.com/xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ax21:code>200</ax21:code>
<ax21:description>Success</ax21:description>
</ns:return>
</ns:getSystemStatusResponse>
</soapenv:Body>
</soapenv:Envelope>
Okay, I created a service but namespace and prefix not match. My service response like that:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<getSystemStatusResponse>
<getSystemStatusResult xmlns:a="http://schemas.datacontract.org/2004/07/WCFLocal.cls" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<a:code>200</a:code>
<a:description>Success</a:description>
</getSystemStatusResult>
</getSystemStatusResponse>
</s:Body>
</s:Envelope>
As you see, tags are different. What is wrong and how can I change prefix in WCF Service?
Thanks for your reply.

WCF request without namespace alias

I have a WCF service that works with a test client generated with SvcUtil.exe.
But my real client is another company that used different technology.
With the generated test client the XML looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<PostModel xmlns="http://tempuri.org/">
<model xmlns:a="http://schemas.datacontract.org/2004/07/SomeName.Models" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<a:Items>
<a:Item>
<a:SomeElement1>SomeValue</a:SomeElement1>
<a:SomeElement2>SomeValue</a:SomeElement2>
</a:Item>
<a:Item>
<a:SomeElement1>SomeValue</a:SomeElement1>
<a:SomeElement2>SomeValue</a:SomeElement2>
</a:Item>
</a:Items>
<a:MoreItems>
<a:MoreItem>
<a:SomeElement3>binary</a:SomeElement3>
</a:MoreItem>
</a:MoreItems>
</model>
</PostModel>
</s:Body>
</s:Envelope>
But the real client sends the xml without alias:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SOAP-ENV:Body>
<PostModel xmlns="http://tempuri.org/">
<model xmlns="http://schemas.datacontract.org/2004/07/SomeName.Models">
<Items>
<Item>
<SomeElement1>SomeValue</SomeElement1>
<SomeElement2>SomeValue</SomeElement2>
</Item>
<Item>
<SomeElement1>SomeValue</SomeElement1>
<SomeElement2>SomeValue</SomeElement2>
</Item>
</Items>
<MoreItems>
<MoreItem>
<SomeElement3>binary</SomeElement3>
</MoreItem>
</MoreItems>
</model>
</PostModel>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
The result is that the model that I receive in the endpoint is NULL.
If I catch the request in fiddler and edit it, add nothing but the alias for the model namespace and add it to the child-elements it works.
Is there a solution for this problem, as far as I know the XML that the client sends is valid XML, aliases are not mandatory.
The difference between the test client XML and the real client XML lies in the namespace of the element model. From the test client:
<PostModel xmlns="http://tempuri.org/">
<model xmlns:a="http://schemas.datacontract.org/2004/07/SomeName.Models" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
This defines an element with local name "model". It has no namespace prefix so exists in the default namespace. However, it does not define a default namespace for itself -- instead it defines namespaces with prefixes "a" and "i". Thus it belongs in whatever default namespace its parent hierarchy defines, in this case "http://tempuri.org/" from its immediate parent.
In the real client's XML, the model element again has no prefix but does have its own default namespace declaration:
<PostModel xmlns="http://tempuri.org/">
<model xmlns="http://schemas.datacontract.org/2004/07/SomeName.Models">
Thus model falls into the namespace "http://schemas.datacontract.org/2004/07/SomeName.Models" rather than the parent's default namespace.
All the child elements of model are in the same namespace in both XML versions. It's only the model element itself which is inconsistent.
This inconsistency would explain the null model in the endpoint.

Removing additional namespace definition in WCF SOAP message

I've got this WSDL(the service is not mine): http://soaptest.webapi-beta.gratka.pl/dom.html?wsdl
When I use WCF generated proxy the method tag in request soap message gets additional namespace definition like:
<q1:zaloguj xmlns:q1="http://soaptest.webapi-beta.gratka.pl/dom.html">
When I use PHP or proxy generated by wsdl.exe this doesn't happen.
I would like to ask, why does WCF do so, and is there possibility to change this behaviour (without using hand-made message modification in BeforeSendRequest)
Below I paste messages generated by PHP and WCF:
PHP one:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://soaptest.webapi-beta.gratka.pl/dom.html" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<ns1:zaloguj>
<login xsi:type="xsd:string">login</login>
<haslo xsi:type="xsd:string">password</haslo>
<klucz_webapi xsi:type="xsd:string">key</klucz_webapi>
<id_kategoria xsi:type="xsd:int">382a</id_kategoria>
<wersja_webapi xsi:type="xsd:int">2</wersja_webapi>
</ns1:zaloguj>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
WCF one:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<q1:zaloguj xmlns:q1="http://soaptest.webapi-beta.gratka.pl/dom.html">
<login xsi:type="xsd:string">login</login>
<haslo xsi:type="xsd:string">password</haslo>
<klucz_webapi xsi:type="xsd:string">key</klucz_webapi>
<id_kategoria xsi:type="xsd:int">382</id_kategoria>
<wersja_webapi xsi:type="xsd:int">2</wersja_webapi>
</q1:zaloguj>
</s:Body>
</s:Envelope>
Are you facing any issues? As far as xml is concerned, both are equivalent. PHP code is declaring the namespace (xmlns:ns1="http://soaptest.webapi-beta.gratka.pl/dom.html") at the root element while WCF is declaring at the point where it is needed - I would believe that this is what WSDL's implementation would be - does not seem to be anything wrong in it.

WCF XML deserialization fail

I've got this WSDL(the service is not mine): http://soaptest.webapi-beta.gratka.pl/dom.html?wsdl
When I get response from method "pobierz_kategorie" I get exception like that
CommunicationException
Error in deserializing body of reply message for operation 'pobierz_kategorie'.
{"There is an error in XML document (2, 501)."} {"The specified type was not recognized: name='kategoria_drzewo', namespace='http://soap.webapi-beta.gratka.pl/dom.html', at ."}
I would like to ask how to modify WSDL or WCF configuration or generated proxy to make it working. When I use PHP to call that method it works so I guess that must be some XMLSerializer problem.
This the response message I get:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://soap.webapi-beta.gratka.pl/dom.html" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<ns1:pobierz_kategorieResponse>
<drzewo_kategorii SOAP-ENC:arrayType="ns1:kategoria_drzewo[48]" xsi:type="ns1:drzewo_kategorii">
<item xsi:type="ns1:kategoria_drzewo">
<id xsi:type="xsd:int">382</id>
<nazwa xsi:type="xsd:string">Dom</nazwa>
<dane xsi:type="xsd:string">0</dane>
<id_rodzic xsi:type="xsd:int">1</id_rodzic>
<poziom xsi:type="xsd:int">0</poziom>
<id_prasa xsi:type="xsd:int">2</id_prasa>
</item>
<item xsi:type="ns1:kategoria_drzewo">
<id xsi:type="xsd:int">8251</id>
<nazwa xsi:type="xsd:string">Pokoje</nazwa>
<dane xsi:type="xsd:string"/>
<id_rodzic xsi:type="xsd:int">382</id_rodzic>
<poziom xsi:type="xsd:int">1</poziom>
<id_prasa xsi:type="xsd:int">0</id_prasa>
</item>
</drzewo_kategorii>
</ns1:pobierz_kategorieResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
That is the request:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:q1="http://soaptest.webapi-beta.gratka.pl/dom.html">
<s:Body s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<q1:pobierz_kategorie>
<sesja xsi:type="xsd:string">ad9e730460e334b916c95533c8da320003ac7e14</sesja>
<id_kategoria xsi:type="xsd:int">382</id_kategoria>
</q1:pobierz_kategorie>
</s:Body>
</s:Envelope>
I've retrieved that WSDL and the response message name does not match what you have above.
Where you have pobierz_kategorieResponse in the wsdl, it is pobierz_kategorie_wyjscie in the WSDL definition.
Message...
<message name="pobierz_kategorie_wyjscie">
<part name="drzewo_kategorii" type="tns:drzewo_kategorii"/>
</message>
Operation...
<operation name="pobierz_kategorie">
<input message="tns:pobierz_kategorie_wejscie"/>
<output message="tns:pobierz_kategorie_wyjscie"/>
</operation>
Maybe you need to regenerate your service reference or point it at a different endpoint.
EDIT
You may have to customize your reference.cs file (your generated WCF client code) to handle the soap array. I haven't done this myself but there is an SO article about it:-
Why won't .NET deserialize my primitive array from a web service?
I'm not 100% sure if this is the same issue as what you are having. It looks like you need to tell WCF explicitly - for this element, this is how you de-serialize the array. Sorry I can't be of more help.
EDIT #2
There is a mismatch between the wsdl published to you 'soaptest' and the actual implementation. Note the namespaces. Or, you've generated your code of a test wsdl endpoint and pointed it at a prod endpoint.See the namespaces below.Your request's namespaces looked like this:-
http://soaptest.webapi-beta.gratka.pl/dom.html
But the response's namespaces looked like this:-
http://soap.webapi-beta.gratka.pl/dom.html
That ain't gonna work!
Try generating your WCF client off
http://soap.webapi-beta.gratka.pl/dom.html?wsdl
instead of off
http://soaptest.webapi-beta.gratka.pl/dom.html?wsdl

How to make C# web service produce soapenv namespace instead of soap?

Is there a way to make a C#/.NET web service which normally produces XML like this
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<DHeader xmlns="http://www.abc.com" />
</soap:Header>
<soap:Body>
<Response xmlns="http://www.abc.com">
<Result>
<ErrorObject ObjectID="string" ErrorCode="" />
</Result>
</Response>
</soap:Body>
</soap:Envelope>
to produce XML like this.
<soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapv:Header>
<DHeader xmlns="http://www.abc.com" />
</soapenv:Header>
<soapenv:Body>
<Response xmlns="http://www.abc.com">
<Result>
<ErrorObject ObjectID="string" ErrorCode="" />
</Result>
</Response>
</soapenv:Body>
</soapenv:Envelope>
This trying solve a problem with an AXIS client consuming a .NET web service. AXIS is choking on the soap namespace and needs a soapenv namespace. Changing the AXIS side is not possible.
any thoughts or comments would be great.
Here is the exact error as requested.
line -1: Element Envelope#http://www.w3.org/2003/05/soap-envelope is not a valid Envelope#http://schemas.xmlsoap.org/soap/envelope/ document or a valid substitution.
soapenv is not a namespace - it's a namespace prefix.
As long as the prefixes refer to the same namespace, soap and soapenv refer to the same thing, and have the identical meaning.
It seems extremely unlikely that any version of AXIS is so badly broken as to treat the prefixes specially. You should assume you have a different problem. Please post the exact error you're receiving.

Categories

Resources