How to convert ASMX Web reference method HttpWebRequest - c#

Recently i started creating a Xamarin-iOS app, which consume ProjectServer PSI WebService. When I add the PSI as WebReference and I try to access the PSI methods I am getting 401 unauthorised error. Interestingly It works fine in local network and but getting error in enterprise network. So I plan to change WebReference to SOAP - HttpwebRequest method.
This is what i Tried
I am trying to get the resource id using this url BaseAddress + pwa/_vti_bin/PSI/Resource.asmx?op=GetCurrentUserUid
<?xml version="1.0" encoding="utf-8"?>
<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:Body>
<GetCurrentUserUid xmlns="http://schemas.microsoft.com/office/project/server/webservices/Resource/" />
</soap:Body>
I am passing the above code as body.
But when i execute this using HttpWebRequest I am getting the error HttpStatusCode InternalServerError System.Net.HttpStatusCode
Also in the response i found the following xml response.
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<s:Fault>
xmlns:a="http://Microsoft.Office.Project.Server">a:ProjectServerFaultCode
</faultcode>
<faultstring>
Unhandled Communication Fault occurred
</faultstring>
<detail>
<string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">
Object reference not set to an instance of an object.</string></detail>
</s:Fault>
</s:Body>
</s:Envelope>
I don't know what' wrong. So my question are,
Is it possible to call PSI method using HttpWebRequest
If not what is the alternative.
Please help. Thanks in advance.

Here's a few items:
The URL should be: BaseAddress + pwa/_vti_bin/PSI/Resource.asmx
SOAP Action Header: ReadResource
In your example, the soap:body should be...
<SOAP:BODY>
<ReadResource>
<resourceUid>value</resourceUid>
</ReadResource>
</SOAP:BODY>

Related

How to send request to a method of Web Service from Postman?

I have an ASMX service, which has the below method. I want to debug this method, so I have put a breakpoint on it. But I am not able to send a request to it successfully, It gives a 404 error.
[WebMethod]
public void RequestNotification()
{
I have tried these options so far.
Page screenshots for reference.
This is how I am calling from the C# code, and this is also not hitting the breakpoint on the method RequestNotification of service. and it's not giving any exceptions also in the C# code.
MyService myService= new MyService ();
myService.RequestNotification();
Update: I have tried as described in the below answer, I am still getting 404.
Please find below the request screenshot.
Using POST call from Postman with XML Body
Demo code.
I will show this Calculator SOAP service for Add operation.
POST URL
http://www.dneonline.com/calculator.asmx
In body with XML ray selection
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<Add xmlns="http://tempuri.org/">
<intA>100</intA>
<intB>200</intB>
</Add>
</soap:Body>
</soap:Envelope>
I got response this from service
<?xml version="1.0" encoding="utf-8"?>
<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>
<AddResponse xmlns="http://tempuri.org/">
<AddResult>300</AddResult>
</AddResponse>
</soap:Body>
</soap:Envelope>
If you click code button from Postman, you can get the curl command too.
curl --location --request POST 'http://www.dneonline.com/calculator.asmx' \
--header 'Content-Type: text/xml; charset=utf-8' \
--header 'SOAPAction: http://tempuri.org/Add' \
--data-raw '<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<Add xmlns="http://tempuri.org/">
<intA>100</intA>
<intB>200</intB>
</Add>
</soap:Body>
</soap:Envelope>
'
#Bench Vue's answer has helped me in solving the issue. I am able to solve the issue with the below request.
Request and Response:

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.

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.

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

Categories

Resources