Sending XML Web Request - c#

We are currently working on a connection to a Web API via XML requests. Our XML statement is as far as correct and also the URL is correct. Nevertheless we receive the following error from the server:
The remote server has returned an error: (403) Inadmissible.
Is there at least one way to get a more detailed error message?
By the way, the API is not from us so we don't have access to the logs of the backend.
XML Request:
<?xml version="1.0" encoding="utf-8"?>
<OTA_PingRQ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" Version="3.3" TimeStamp="2020-12-09T13:53:57" PrimaryLangID="en" Target="Production">
<EchoData><![CDATA[Hello World]]></EchoData>
</OTA_PingRQ>
Web Call:
using (var wb = new WebClient())
{
var data = new NameValueCollection();
data["otaRQ"] = xml;
var response =
wb.UploadValues("http://backend.cultuzz.com:7380/cultswitch/processOTA",
"POST", data);
string responseInString = Encoding.UTF8.GetString(response);
MessageBox.Show(responseInString);
}

If I use the ping example as documented here it works. Change your xml to this:
string xml = #"<OTA_PingRQ xmlns=""http://www.opentravel.org/OTA/2003/05""
Version=""3.30"" TimeStamp=""2011-07-24T10:07:24"" Target=""Production"">
<EchoData><![CDATA[Hello World!!]]></EchoData> </OTA_PingRQ>";
response:
<?xml version="1.0" encoding="UTF-8"?>
<OTA_PingRS PrimaryLangID="en" Target="Production"
TimeStamp="2020-12-09T13:46:19" Version="3.00" xmlns="http://www.opentravel.org/OTA/2003/05">
<Success/>
<EchoData><![CDATA[Hello World!!]]></EchoData>
</OTA_PingRS>

Related

SOAP Client using C#

I have Soap web service https://test-submit.health263.systems:8081/apacewebservices/AMF1_0?wsdl. This has a method called process. My question is how do I create soap client to send a request, that submits/Retrieves information from the server. The example XML for the request is shown below:
<?xml version="1.0" encoding="UTF-8"?>
<Member xmlns="urn:apace:member:format:1.0">
<Request>
<Transaction>
<VersionNumber>1.0</VersionNumber>
<Number>434252-342234-6765</Number>
<SystemIdentifier>SYSTEM999</SystemIdentifier>
<DestinationCode>APACE</DestinationCode>
<ClientCountryCode>ZA</ClientCountryCode>
<Timestamp TimeZone="Africa/Johannesburg">20160601123456</Timestamp>
<TestIndicator>Y</TestIndicator>
<User>ProviderX/Jane Doe</User>
</Transaction>
<MembershipLookup>
<Funder>AFunder</Funder>
<WithMembershipNumber>
<MembershipNumber>123456789</MembershipNumber>
</WithMembershipNumber>
</MembershipLookup>
</Request>
</Member>
The response message is structured as follows :
<?xml version="1.0" encoding="UTF-8"?>
<Member xmlns="urn:apace:member:format:1.0">
<Response>
<Transaction>
<VersionNumber>1.0</VersionNumber>
<Number>434252-342234-6765</Number>
<Status>S</Status>
<Timestamp TimeZone="Africa/Johannesburg">20160601123500</Timestamp>
</Transaction>
<Membership NumberOfBeneficiaryRecords="2">
<Funder>AFunder</Funder>
<MembershipNumber>123456789</MembershipNumber>
<Beneficiary SequenceNumber="1">
<DependentCode>00</DependentCode>
<Type>P</Type>
<Status>A</Status>
<BiometricEnrolmentStatus>Y</BiometricEnrolmentStatus>
</Beneficiary>
<Beneficiary SequenceNumber="2">
<DependentCode>01</DependentCode>
<Type>D</Type>
<Status>A</Status>
<BiometricEnrolmentStatus>Y</BiometricEnrolmentStatus>
</Beneficiary>
</Membership>
</Response>
</Member>
Please help I am really stuck, Haven't used SOAP services with C#, I have tried examples online but the structure does not follow my message structures are more complicated
The actual message structure is structured as follows:
<soap:Envelope
xmlns:soap="http://www.w3.org/2003/05/soap-envelope"
xmlns:apac="http://apace.systems/apacewebservices/"
xmlns:urn="urn:apace:member:format:1.1">
<soap:Header>
<apac:secureToken>Token66657752</apac:secureToken>
</soap:Header>
<soap:Body>
<apac:process>
<apac:request>
<Member
xmlns="urn:apace:member:format:1.1">
<Request>
<Transaction>
<VersionNumber>1.1</VersionNumber>
<Number>30074</Number>
<SystemIdentifier>LIFEHEALTH</SystemIdentifier>
<DestinationCode>HEALTH263</DestinationCode>
<ClientCountryCode>ZA</ClientCountryCode>
<Timestamp TimeZone="Africa/Johannesburg">20200705123456</Timestamp>
<TestIndicator>Y</TestIndicator>
<User>CIMSZW/Jane Doe</User>
</Transaction>
<MembershipLookup>
<IncludeDetail>Y</IncludeDetail>
<Funder>CIMSZWA</Funder>
<WithMembershipNumber>
<MembershipNumber>11117374</MembershipNumber>
<DependentCode>00</DependentCode>
</WithMembershipNumber>
</MembershipLookup>
</Request>
</Member>
</apac:request>
</apac:process>
</soap:Body>
</soap:Envelope>
Hw do I create the SOAP envelope and the Header part with the Security Key Token
You have two options
Add as service reference , it will genrate the
use Visual studio developer prompt and consume the service using a proxy class
svcutil.exe https://test-submit.health263.systems:8081/apacewebservices/AMF1_0?wsdl /t:code /n:*,SampleNamespace /o:C:\Service\sampleServiceProxy.cs /config:C:\Service\sampleService.config /ct:System.Collections.Generic.List`1
You can use a couple different system libraries to create an HttpWebRequest, create custom xml, and insert that xml into your request before you send it. (system.net, system.xml.linq, system.io)
I was able to hit your web service but got a 500 error. (Hopefully you see a log or that wasn't yours!)
Here's a simple class that can call a SOAP web service. It's almost the xml that you need but might need some tweaking. If you're having issues making custom xml this may be a possible solution.
using System;
using System.IO;
using System.Net;
using System.Text;
using System.Xml.Linq;
namespace ConsoleApp1
{
/// <summary>
/// Random class
/// </summary>
class Class1
{
/// <summary>
/// Function that calls a SOAP web service
/// </summary>
public void CallSOAP()
{
try
{
// Construct http post request
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(new Uri("https://test-submit.health263.systems:8081/apacewebservices/AMF1_0"));
request.Method = "POST";
request.ContentType = "application/xml";
request.Accept = "application/xml";
// Setting a namespace for your xml
// I'm not sure the timezone one is set up properly
XNamespace soap = "urn:apace:member:format:1.0";
XNamespace timezone = "TimeZone=\"Africa/Johannesburg\"";
// This constructs your xml using the LINQ library. I modeled after your demo, but needs tweaking as I get 500 error from server.
XElement requestXML =
new XElement(soap + "Member",
new XElement("Request",
new XElement("Transaction",
new XElement("VersionNumber", "1.0"),
new XElement("Number", "434252 - 342234 - 6765"),
new XElement("SystemIdentifier", "SYSTEM999"),
new XElement("DestinationCode", "APACE"),
new XElement("ClientCountryCode", "ZA"),
new XElement(timezone + "Timestamp", "20160601123456"),
new XElement("TestIndicator", "Y"),
new XElement("User", "ProviderX/Jane Doe")
),
new XElement("MembershipLookup",
new XElement("Funder", "AFunder"),
new XElement("WithMembershipNumber",
new XElement("MembershipNumber", 123456789)
)
)
)
);
// Convert the xml into a stream that we write to our request
byte[] bytes = Encoding.UTF8.GetBytes(requestXML.ToString());
request.ContentLength = bytes.Length;
using (Stream putStream = request.GetRequestStream())
{
putStream.Write(bytes, 0, bytes.Length);
}
// Execute the request and get an xml response "reader". You can read all xml at once or line by line
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
using (StreamReader reader = new StreamReader(response.GetResponseStream()))
{
var streamData = reader.ReadToEnd();
}
}
catch (Exception ex)
{
// Write exception to console & wait for key press
Console.WriteLine(ex.Message + ex.StackTrace);
Console.ReadKey();
}
}
}
}

Connecting To Web Services through Xamarin

I am new to Xamarin and am trying to connect to my client web services whose address is http://smartasset-utw.malaysiaairports.com.my:5010/service1.asmx?op=GetUserLogin. This is used to authenticate logins. The code that I have used is below.
var httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("text/xml"));
httpClient.DefaultRequestHeaders.Add("SOAPAction", "http://smartasset-utw.malaysiaairports.com.my:5010/service1.asmx?WSDL");
string wUser = "XXXXX";
string wPassword = "xxxxxxxx";
string soapstr = string.Format(#"<?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>
<GetUserLogin xmlns=""http://tempuri.org/"">
<userName>{0}</userName>
<password>{1}</password>
</GetUserLogin>
</soap:Body>
</soap:Envelope>", wUser, wPassword);
var response = httpClient.PostAsync("http://smartasset-utw.malaysiaairports.com.my:5010/service1.asmx?WSDL", new StringContent(soapstr, Encoding.UTF8, "text/xml")).Result;
var content = response.Content.ReadAsStringAsync().Result;
Unfortunately, the response that I get is:
<?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><soap:Fault><faultcode>soap:Client</faultcode><faultstring>Server did not recognize the value of HTTP Header SOAPAction: http://smartasset-utw.malaysiaairports.com.my:5010/service1.asmx.</faultstring><detail /></soap:Fault></soap:Body></soap:Envelope>
Any help would be appreciated,
Thanks

Consume Web Service with soap:mustUnderstand attribute

This is my sample Code for Web service. I'm new to SOAP application if someone can spot any problem here it's much appreciated. This error only happened if mustUnderstand attribute ="1"
[WebService(Namespace = "http://www.xxxx.co.uk/Integration/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
public class ADNHeaderContact : System.Web.Services.WebService
{
public MyHeader myHeader;
[WebMethod]
[SoapHeader("myHeader")]
public string HelloWorld()
{
XmlDocument xmlSoapRequest = new XmlDocument();
using (Stream receiveStream = HttpContext.Current.Request.InputStream)
{
receiveStream.Position = 0;
using (StreamReader readStream =
new StreamReader(receiveStream, Encoding.UTF8))
{
xmlSoapRequest.Load(readStream);
}
}
using (XmlBreaker readxml = new XmlBreaker())
{
using (ReponseSaveApplications respose = new ReponseSaveApplications())
{
return ("Hello");
}
};
}
}
My Postman post request
<?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:Header>
<MyHeader soap:mustUnderstand="true" xmlns="http:www.xxxx.co.uk/Integration/">
<MyValue>string</MyValue>
</MyHeader>
</soap:Header
<soap:Body>
<HelloWorld xmlns="http://www.xxxx.co.uk/Integration/" />
</soap:Body>
</soap:Envelope>
My Postman post response
<?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>
<soap:Fault>
<faultcode>soap:MustUnderstand</faultcode>
<faultstring>System.Web.Services.Protocols.SoapHeaderException: SOAP header MyHeader was not understood.
at System.Web.Services.Protocols.SoapHeaderHandling.SetHeaderMembers(SoapHeaderCollection headers, Object target, SoapHeaderMapping[] mappings, SoapHeaderDirection direction, Boolean client)
at System.Web.Services.Protocols.SoapServerProtocol.CreateServerInstance()
at System.Web.Services.Protocols.WebServiceHandler.Invoke()
at System.Web.Services.Protocols.WebServiceHandler.CoreProcessRequest()</faultstring>
</soap:Fault>
</soap:Body>
</soap:Envelope>
SoapHeader.MustUnderstand Property
When an XML Web service client adds a SOAP header to an XML Web
service method call with the MustUnderstand property set to true, the
XML Web service method must set the DidUnderstand property to true;
otherwise, a SoapHeaderException is thrown back to the XML Web service
client by ASP.NET.

XML deserialization: Data at the root level is invalid. Line 1 position 1. Tried almost everything

I'm trying to deserialize XML. I'm getting the XML to string(which works fine) but then when I try to parse it I'm getting and error "Data at the root level is invalid. Line 1 position 1"
I tried everything which I found here. Read a lot of threads and tried all the suggestion: reading this to byte array, to stream, trying different Xml classes, removing BOM.
Here is my code(you can see the XML file under the link in code):
public class XmlParser
{
private List<CurrencyUnit> _currenciesList = new List<CurrencyUnit>();
public List<CurrencyUnit> CurrenciesList { get => _currenciesList; set => _currenciesList = value; }
public async void GetXML()
{
Uri uri = new Uri("http://api.nbp.pl/api/exchangerates/tables/A/");
HttpClient client = new HttpClient();
HttpResponseMessage httpResponse = await client.GetAsync(uri);
string response = await httpResponse.Content.ReadAsStringAsync();
XDocument xDocument = XDocument.Parse(response);
foreach (var element in xDocument.Descendants("Rate"))
{
CurrencyUnit unit = new CurrencyUnit();
unit.Currency = element.Element("Currency").Value.ToString();
unit.Code = element.Element("Code").Value.ToString();
unit.Mid = element.Element("Mid").Value.ToString();
CurrenciesList.Add(unit);
}
}
}
Here is part of the XML(you can see whole under the link from code):
<?xml version="1.0" encoding="UTF-8"?>
<ArrayOfExchangeRatesTable xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<ExchangeRatesTable>
<Table>A</Table>
<No>056/A/NBP/2018</No>
<EffectiveDate>2018-03-20</EffectiveDate>
<Rates>
<Rate>
<Currency>bat (Tajlandia)</Currency>
<Code>THB</Code>
<Mid>0.1100</Mid>
</Rate>
That endpoint returns JSON if the request headers don't explicitly ask for XML, and you can't parse JSON as XML.
Your browser sends something like Accept: text/html,[...]application/xml by default, whereas HttpClient sends none. In that case, you get JSON in return. You could've seen this if you'd inspected the response variable while debugging.
Either deserialize the response into JSON, or pass the Accept: application/xml request header as explained in Forcing HttpClient to use Content-Type: text/xml.
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/xml"));

Consume SOAP/SSO using C#

Which is the easiest way to consume a WSDL SOAP/SSO using C# ?
This is a third party system and i get this response:
HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: length
<?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>
<RetornaEstadosPorMarcaResponse xmlns="http://WebService-MultiLogin-2013/">
<RetornaEstadosPorMarcaResult>
<EstadosMDL>
<ID>int</ID>
<Nome>string</Nome>
<Sigla>string</Sigla>
</EstadosMDL>
<EstadosMDL>
<ID>int</ID>
<Nome>string</Nome>
<Sigla>string</Sigla>
</EstadosMDL>
</RetornaEstadosPorMarcaResult>
</RetornaEstadosPorMarcaResponse>
</soap:Body>
</soap:Envelope>
And this is how i'm calling it:
public AdminMaster.RetornaEstadosPorMarca.Estados ssoEstados = new AdminMaster.RetornaEstadosPorMarca.Estados();
ssoEstados.RetornaEstadosPorMarca(Library.Configuracoes.ChaveSSO, Convert.ToInt16(Library.Configuracoes.Marca));
I have already tried to receive it as a string and format it to use as XML but it didn't work because of <soap:Body> and <soap:Envelope>, i get an error because i have the ':' on the name and i don't think that's the easiest way to do it.
So, how do i access the information from the response ? Is there another way ?
EDIT:
After several hours and tests i finally found the problem, "my" SOAP also gives me a class to create a object to receive the response, i only had to use it:
//Here i have the object with the methods
private Library.ssoEstados.Estados objEstadosSSO = new Library.ssoEstados.Estados();
//Here i have the object to receive the response
private Library.ssoEstados.EstadosMDL[] objEstadosMDL;
Than it was only a matter of read the values i wanted and send it to my own object.
XmlDocument xDoc = new XmlDocument();
xDoc.LoadXml(inputXml);
XmlNamespaceManager namespaces = new XmlNamespaceManager(xDoc.NameTable);
namespaces.AddNamespace("soapenv", "http://schemas.xmlsoap.org/soap/envelope/");
namespaces.AddNamespace("ns2", "http://tempuri.org/");
XmlNode accountNode = xDoc.SelectSingleNode("/soapenv:Envelope/soapenv:Body/ns2:RetornaEstadosPorMarcaResponse/RetornaEstadosPorMarcaResult", namespaces);
XmlNode xnlAccount = accountNode.ChildNodes[0];
if (xnlAccount != null)
{
XmlDocument xAccount = new XmlDocument();
xAccount.LoadXml(xnlAccount.InnerText);
}
inputXml is a string containing your response xml.

Categories

Resources