Consume SOAP/SSO using C# - 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.

Related

Sending XML Web Request

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>

How to pass XML input to API call using C#

I have below XML input. I need to call API and pass this as input but values will change dynamically. How can I build this input structure?
<?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>
<Test xmlns="http://tempuri.org/">
<acc>test</acc>
<pass>abc</pass>
<xmlInvData>
<![CDATA[
<MyData>
<name>test</name>
<number>900</number>
</MyData>
]]>
</xmlInvData>
<username>test</username>
<password>123</password>
</Test>
</soap:Body>
</soap:Envelope>
I have MyData Class in C# which can be useful to setup name and number values.
But how can I form a complete structure and pass to Api call? soap:Envelop and soap body?
HttpClient httpClient = new HttpClient();
string requestUri = "https://testurl";
var byteArray = Encoding.ASCII.GetBytes("username:password");
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray));
HttpResponseMessage response = await httpClient.PostAsync(requestUri, httpContent);
I need to understand how to form httpContent as above my input json.
Assuming you've built the data structure and serialized it to a string called xml:
var httpContent = new StringContent(xml, Encoding.UTF8, "application/xml");

cs0103 the name'debuggerDisplayProxy' does not exist in the current context

I'm trying to construct a soap envelope to send data and, when I instantiate XmlDocument object, I'm getting this error "cs0103 the name'debuggerDisplayProxy' does not exist in the current context". I don't know what it is or how to solve it. I searched on the web and didn't find anything useful. Could you help, please?
Below, is the code where I try to do the envelope:
private static System.Xml.XmlDocument CreateSoapEnvelope(string xml)
{
var soapEnvelope = new System.Xml.XmlDocument();
soapEnvelope.LoadXml(#"<?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>
<HelloWorld3 xmlns=""
http://localhost:52700/api/SOAPService/PostObject"">"
+ xml +
"</HelloWorld3></soap:Body></soap:Envelope>");
return soapEnvelope;
}
Below, the error:

XmlDocument CreateElement without xmlns under a prefixed element

I'm trying to compose a SOAP request to ebay FindingAPI web service by using C# XmlDocument class in the following code:
XmlDocument doc = new XmlDocument();
XmlElement root = (XmlElement)doc.AppendChild(doc.CreateElement("soap", "Envelope", "http://www.w3.org/2003/05/soap-envelope"));
root.SetAttribute("xmlns", "http://www.ebay.com/marketplace/search/v1/services");
XmlElement header = (XmlElement)root.AppendChild(doc.CreateElement("soap", "Header", "http://www.w3.org/2003/05/soap-envelope"));
XmlElement body = (XmlElement)root.AppendChild(doc.CreateElement("soap", "Body", "http://www.w3.org/2003/05/soap-envelope"));
XmlElement request = (XmlElement)body.AppendChild(doc.CreateElement("findItemsByKeywordsRequest"));
XmlElement param = (XmlElement)request.AppendChild(doc.CreateElement("keywords"));
param.InnerText = "harry potter phoenix";
And, the XML output of above code is:
<soap:Envelope xmlns="http://www.ebay.com/marketplace/search/v1/services" xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
<soap:Header />
<soap:Body>
<findItemsByKeywordsRequest xmlns="">
<keywords>harry potter phoenix</keywords>
</findItemsByKeywordsRequest>
</soap:Body>
</soap:Envelope>
However, this XML can't be recognized by the server because of the extra xmlns="" attribute in the findItemsByKeywordsRequest element. The desired XML output should be as below:
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns="http://www.ebay.com/marketplace/search/v1/services">
<soap:Header/>
<soap:Body>
<findItemsByKeywordsRequest>
<keywords>harry potter phoenix</keywords>
</findItemsByKeywordsRequest>
</soap:Body>
</soap:Envelope>
Does anyone know what is the problem of my code and please give me some hints. Thanks!
Because your document has default namespace declared in the most outer element you have to repeat that namespace on every child element to avoid adding additional empty one.
Change request and param elements declaration to contain "http://www.ebay.com/marketplace/search/v1/services" namespace
XmlElement request = (XmlElement)body.AppendChild(doc.CreateElement("findItemsByKeywordsRequest", "http://www.ebay.com/marketplace/search/v1/services"));
XmlElement param = (XmlElement)request.AppendChild(doc.CreateElement("keywords", "http://www.ebay.com/marketplace/search/v1/services"));
With these changes your code produces following XML:
<soap:Envelope xmlns="http://www.ebay.com/marketplace/search/v1/services" xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
<soap:Header />
<soap:Body>
<findItemsByKeywordsRequest>
<keywords>harry potter phoenix</keywords>
</findItemsByKeywordsRequest>
</soap:Body>
</soap:Envelope>

WCF Method is returning xml fragment but no xml UTF-8 header

My method does not return the header, just the root element xml.
internal Message CreateReturnMessage(string output, string contentType)
{
// create dictionaryReader for the Message
byte[] resultBytes = Encoding.UTF8.GetBytes(output);
XmlDictionaryReader xdr = XmlDictionaryReader.CreateTextReader(resultBytes, 0, resultBytes.Length, Encoding.UTF8, XmlDictionaryReaderQuotas.Max, null);
if (WebOperationContext.Current != null)
WebOperationContext.Current.OutgoingResponse.ContentType = contentType;
// create Message
return Message.CreateMessage(MessageVersion.None, "", xdr);
}
However, the output I get is:
<Test>
<Message>Hello World!</Message>
</Test>
I would like the output to render as:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Test>
<Message>Hello World!</Message>
</Test>
Have a look at this URL http://blogs.msdn.com/b/wifry/archive/2007/05/15/wcf-bodywriter-and-raw-xml-problems.aspx
Pass the xml string to the custom bodywriter and it will output xml declaration
so assuming output param is coming in as...
<Test>
<Message>Hello World!</Message>
</Test>
What do you expect to happen? You aren't writing xml, just reading the output string through a reader. The reader class won't add anything to your fragment, it's a reader, not a writer.
You could so something like this instead...It will parse your output as xml and then you can add a declaration before giving it to the message.
var output = "<Test><Message>Hello World!</Message></Test>";
var xd = XDocument.Parse(output);
xd.Declaration = new XDeclaration("1.0", "utf-8", "yes");
return Message.CreateMessage(version, messageFault, xd.ToString());

Categories

Resources