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");
Related
I'm calling Soap method and receiving HttpResponseMessage as below :
HttpResponseMessage createResponse = await ExecuteMyEndPoint(endpoint, requestXMLstring, client);
And reading that as a String Response:
string responseMessage = await createResponse.Content.ReadAsStringAsync();
This is the Sample Response :
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns1:createWorkflowResponse xmlns:ns1="http://www.somedomain.com/xml/workflow">
<WorkflowExternalReference xmlns:ns3="http://www.somedomain.com/xml/integration">123456789</WorkflowExternalReference>
</ns1:createWorkflowResponse>
</soap:Body>
</soap:Envelope>
I want to convert this response to C# object. How to do that?
I am trying to send a xml to a server and it always throw an exception Malformed request: Premature end of file.. . Using the Postman it works well but using HttpClient it doesn't, I think the problem is with headers what server needs is Content-Type", "application/xml and I cannot do it works
How could I fix it ?
trying
//HttpClient
HttpClient hClient = new HttpClient();
hClient.DefaultRequestHeaders.TryAddWithoutValidation("Content-Type", "application/xml");
//post
var contentString = new StringContent(xml, Encoding.UTF8, "application/xml");
HttpResponseMessage response = hClient.PostAsync(URL_FINAL, contentString).GetAwaiter().GetResult();
var resultContent = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();
xml
<?xml version="1.0" encoding="utf-16"?>
<payment xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<mode>default</mode>
<method>creditCard</method>
<sender>
<name>Meu Nome</name>
<email>email#gmail.com</email>
<phone>
<areaCode>17</areaCode>
<number>9999999999</number>
</phone>
<documents>
<document>
<type>CPF</type>
<value>9999999999</value>
</document>
</documents>
<hash>5e5240axxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxea8a</hash>
</sender>
<currency>BRL</currency>
<notificationURL>https://dominio.com/StatusPagamentoTransaction</notificationURL>
<items>
<item>
<id>2</id>
<description>produto</description>
<quantity>2</quantity>
<amount>2.00</amount>
</item>
</items>
<extraAmount>0.00</extraAmount>
<reference>R748</reference>
<shipping>
<addressRequired>false</addressRequired>
</shipping>
<creditCard>
<token>91999999999999999999b0f</token>
<installment>
<quantity>1</quantity>
<value>2.00</value>
</installment>
<holder>
<name>nome proprietario cartao</name>
<documents>
<document>
<type>CPF</type>
<value>99999999999</value>
</document>
</documents>
<birthDate>18/12/1964</birthDate>
<phone>
<areaCode>17</areaCode>
<number>99999999</number>
</phone>
</holder>
<billingAddress>
<street>rua A</street>
<number>3333</number>
<district>bairro</district>
<city>cidade</city>
<state>SP</state>
<country>BRA</country>
<postalCode>05407002</postalCode>
</billingAddress>
</creditCard>
</payment>
Exception
<?xml version="1.0" encoding="ISO-8859-1" standalone="yes"?><errors><error><code>11213</code><message>Malformed request: Premature end of file..</message></error></errors>
Try to set Accept header
hClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/xml"));
Instead of
hClient.DefaultRequestHeaders.TryAddWithoutValidation("Content-Type", "application/xml");
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
Here is what the header is supposed to look like
<soap:Header>
<AuthenticationHeader>
<UserName>string</UserName>
<Password>string</Password>
</AuthenticationHeader>
</soap:Header>
Here is what I've tried:
string username = "TheUserName";
string password = "ThePassword";
HttpRequestMessage requestMessage = new HttpRequestMessage(method, uri);
requestMessage.Headers.Add("UserName", username);
requestMessage.Headers.Add("Password", password);
Maybe I have to somehow set the authorization header?
requestMessage.Headers.Authorization = ??
I feel like somehow I have to "build" that AuthenticationHeader element but I'm not sure how to do that. Any suggestions?
Edit: Full SOAP Envelope
?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>
<AuthenticationHeader xmlns="http://www.test.com/testing/Security">
<UserName>string</UserName>
<Password>string</Password>
</AuthenticationHeader>
</soap:Header>
<soap:Body>
<GetMeSomething xmlns="http://www.test.com/testing/WorkFileCatalog">
<Param1>string</Param1>
<Param2>string</Param2>
<XMLRetMess>string</XMLRetMess>
</GetMeSomething>
</soap:Body>
</soap:Envelope>
Given the provided OP, the following Unit Test was done as a proof of concept of how you can populate the header message header and create a request.
[TestClass]
public class SOAP_UnitTests {
private HttpMethod method;
private string uri;
private string action;
[TestMethod]
public void _Add_SOAP_Auth_Header_Details_With_HttpRequestMessage() {
string username = "TheUserName";
string password = "ThePassword";
var xml = ConstructSoapEnvelope();
var doc = XDocument.Parse(xml);
var authHeader = doc.Descendants("{http://www.test.com/testing/Security}AuthenticationHeader").FirstOrDefault();
if (authHeader != null) {
authHeader.Element(authHeader.GetDefaultNamespace() + "UserName").Value = username;
authHeader.Element(authHeader.GetDefaultNamespace() + "Password").Value = password;
}
string envelope = doc.ToString();
var request = CreateRequest(method, uri, action, doc);
request.Content = new StringContent(envelope, Encoding.UTF8, "text/xml");
//request is now ready to be sent via HttpClient
//client.SendAsync(request);
}
private static HttpRequestMessage CreateRequest(HttpMethod method, string url, string action, XDocument soapEnvelopeXml) {
var request = new HttpRequestMessage(method: method, requestUri: url);
request.Headers.Add("SOAPAction", action);
request.Headers.Add("ContentType", "text/xml;charset=\"utf-8\"");
request.Headers.Add("Accept", "text/xml");
request.Content = new StringContent(soapEnvelopeXml.ToString(), Encoding.UTF8, "text/xml"); ;
return request;
}
private string ConstructSoapEnvelope() {
var message = #"<?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>
<AuthenticationHeader xmlns='http://www.test.com/testing/Security'>
<UserName>string</UserName>
<Password>string</Password>
</AuthenticationHeader>
</soap:Header>
<soap:Body>
<GetMeSomething xmlns='http://www.test.com/testing/WorkFileCatalog'>
<Param1>string</Param1>
<Param2>string</Param2>
<XMLRetMess>string</XMLRetMess>
</GetMeSomething>
</soap:Body>
</soap:Envelope>
";
return message;
}
}
If you are using HttpClient to POST a request, then you should build the full XML request.
In other words, you would build the exact Soap XML including all the elements
string requestXml = your actual full soap xml
string result = HttpClient.Post ( your actual xml )
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.