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

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.

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.

Custom fault type for an ASP.NET webservice

I am developing a webservice in C#, ASP.NET. By default, when my webservice throws exception, using
throw new SoapException("ERROR_MESSAGE", SoapException.ClientFaultCode);
This outputs the following xml:
<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">
<soap:Body>
<soap:Fault>
<faultcode>soap:Client</faultcode>
<faultstring>ERROR_MESSAGE</faultstring>
<detail/>
</soap:Fault>
</soap:Body>
</soap:Envelope>
However, I have to implement a custom fault type that uses different xml:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body xmlns:cst="http://cust.om/Namespace">
<cst:Fault>
<cst:errorMessage>ERROR_MESSAGE</cst:errorMessage>
</cst:Fault>
</soap:Body>
</soap:Envelope>
They expect that this fault type appears also in the wsdl file that is generated by http-GETting ?wsdl, surfacing there as element.
Is this even possible? Well, everything is possible by rewriting the exiting stream with replaced string, but I'd prefer less brutal approach. Besides, that kind of fix would not cause the elements to appear in the auto-generated wsdl spec.

SOAP fault message

I have to send a SOAP fault message over HTTP to another web service if something goes wrong with a server, so I have this code:
<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>
<Response status="1">
<Description>DESC</Description>
<Errors>
<Error>500</Error>
</Errors>
</Response>
</soapenv:Body>
</soapenv:Envelope>
Is this a properly formatted SOAP fault message?
Is this a properly formatted SOAP fault message?
No it isn't. It should look something like this:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<soap:Fault>
<faultcode>...</faultcode>
<faultstring>...</faultstring>
<detail>...</detail>
</soap:Fault>
</soap:Body>
</soap:Envelope>
The SOAP specification specifies what a fault is. Yours looks like an error result object of some sort which has some disadvantages as explained here for example.
Your WS framework should properly generate faults if you throw exceptions. If you are not using a framework but building the fault in some other way, then it must look like in my example above or it can't be called a SOAP fault.
Hey Bogdan I wrote this code and works like a charm!
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soap:Body>
<soap:Fault>
<faultcode>500</faultcode>
<faultstring>SERVER ERROR</faultstring>
<detail>
<Response_status>1</Response_status>
<Description>DESCRIPTION</Description>
</detail>
</soap:Fault>
</soap:Body>
</soap:Envelope>
But another question how to send a SOAP success message with a http code 200 an also I have to have some additional parameters in the message, this is a part of it
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soap:Body>
<Response_status>0</Response_status>
<Description>SUCCESS</Description>
</soap:Body>
</soap:Envelope>
So with this also I have to send code 200, how to write that can I write it like this
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soap:Body>
<soap:Fault>
<faultcode>200</faultcode>
<faultstring>OK</faultstring>
<detail>
<Response_status>0</Response_status>
<Description>SUCCESS</Description>
</detail>
</soap:Fault>
</soap:Body>
</soap:Envelope>

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.

Categories

Resources