I am just learning how to send SOAP requests to my AVM FritzBox 7270 router using C#.
Here ist my method that sends a SOAP request to the router:
private string Execute(string controlUrl, string serviceType, string action)
{
WebRequest webRequest = WebRequest.Create("http://fritz.box:49000" + controlUrl);
HttpWebRequest httpRequest = (HttpWebRequest)webRequest;
httpRequest.Method = "POST";
httpRequest.ContentType = "text/xml; charset=utf-8";
httpRequest.Headers.Add("SOAPACTION", string.Format("{0}#{1}", serviceType, action));
httpRequest.ProtocolVersion = HttpVersion.Version11;
httpRequest.Credentials = new NetworkCredential("username", "password");
Stream requestStream = httpRequest.GetRequestStream();
StreamWriter streamWriter = new StreamWriter(requestStream, Encoding.ASCII);
streamWriter.Write(GetBody(serviceType, action));
streamWriter.Close();
//Get the Response
try
{
HttpWebResponse wr = (HttpWebResponse)httpRequest.GetResponse();
StreamReader srd = new StreamReader(wr.GetResponseStream());
return srd.ReadToEnd();
}
catch (WebException)
{
return null;
}
}
Function GetBody:
private string GetBody(string serviceType, string action)
{
const string fmt = #"<?xml version=""1.0"" encoding=""utf-8""?>
<s:Envelope xmlns:s=""http://schemas.xmlsoap.org/soap/envelope/"" s:encodingStyle=""http://schemas.xmlsoap.org/soap/encoding/"">
<s:Body>
<u:{0} xmlns:u=""{1}"" />
</s:Body>
</s:Envelope>
";
return string.Format(fmt, action, serviceType);
}
}
I tested this method with parameters that I found anywhere in the internet:
controlUrl = "/upnp/control/WANIPConn1"
serviceType = "urn:schemas-upnp-org:service:WANIPConnection:1"
action = "GetExternalIPAddress"
This works well.
However, I think I should go the official way and first send a request
http://fritz.box:49000/tr64desc.xml
to receive parameters valid for my actual router. In the response to this request I find the following node:
<service>
<serviceType>urn:dslforum-org:service:WANIPConnection:1</serviceType>
<serviceId>urn:WANIPConnection-com:serviceId:WANIPConnection1</serviceId>
<controlURL>/upnp/control/wanipconnection1</controlURL>
<eventSubURL>/upnp/control/wanipconnection1</eventSubURL>
<SCPDURL>/wanipconnSCPD.xml</SCPDURL>
</service>
Using these values for serviceId and controlUrl, I get error 500 (Internal Server Error).
Who can help me? What is wrong in my code?
I think the problem is solved:
There seem to be a lot of undocumeted features of the Fritz.Box, and the pararmeters I found in the internet oviously are part of thease features.
With
<service>
<serviceType>urn:dslforum-org:service:WANPPPConnection:1</serviceType>
<serviceId>urn:WANPPPConnection-com:serviceId:WANPPPConnection1</serviceId>
<controlURL>/upnp/control/wanpppconn1</controlURL>
<eventSubURL>/upnp/control/wanpppconn1</eventSubURL>
<SCPDURL>/wanpppconnSCPD.xml</SCPDURL>
</service>
I can call
GetExternalIPAddress
without problems.
Related
I have a VBA code which calls a SOAP service and receives an XML response.
I want to write a C# REST API to call this SOAP service in a similar way.
Referring to the articles here I wrote a SOAP request but it does not works and returns the below error. I am able to call this SOAP service from the VBA code and also POST MAN. Can some one please explain what's wrong with my code?
public class CallSOAPAPIController : ApiController
{
[HttpGet]
public string Extract()
{
HttpWebRequest request = CreateWebRequest();
XmlDocument soapEnvelopeXml = new XmlDocument();
soapEnvelopeXml.LoadXml(#"<?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/"" xmlns:inc=""http://www.test-xyz.com/""><soap:Body>Calendar #Year#Month#1</soap:Body></soap:Envelope>");
using (Stream stream = request.GetRequestStream())
{
soapEnvelopeXml.Save(stream);
}
using (WebResponse response = request.GetResponse())
{
using (StreamReader rd = new StreamReader(response.GetResponseStream()))
{
soapResult = rd.ReadToEnd();
Console.WriteLine(soapResult);
}
}
return soapResult;
}
/// <summary>
/// Create a soap webrequest to [Url]
/// </summary>
/// <returns></returns>
public static HttpWebRequest CreateWebRequest()
{
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(#"http://test.production-xyz.com/listofemployees.do?getdetails=all&SOAP");
webRequest.Headers.Add(#"SOAP:Action");
webRequest.ContentType = "text/xml;charset=\"utf-8\"";
webRequest.Accept = "text/xml";
webRequest.Method = "POST";
CallSOAPAPIController obj = new CallSOAPAPIController();
string base64Credentials = obj.GetEncodedCredentials();
webRequest.Headers.Add("Authorization", "Basic " + base64Credentials);
return webRequest;
}
private string GetEncodedCredentials()
{
string m_Username = "XXXXXX";
string m_Password = "XXXXXX";
string mergedCredentials = string.Format("{0}:{1}", m_Username, m_Password);
byte[] byteCredentials = UTF8Encoding.UTF8.GetBytes(mergedCredentials);
return Convert.ToBase64String(byteCredentials);
}
}
The error I get : "The remote server returned an error:(401) Unauthorized"
Unauthorized(401)
I need to have a Client authentication via a certificate or better a keystorefile (myfile.p12).
I used it in SoapUI and there it worked. I got the Infos about the available requests.
If I try to add a Service reference to my empty Project, it always fails.
There was an error downloading 'https://MYURL/api?wsdl/$metadata'.The request was aborted: Could not create SSL/TLS secure channel. Metadata contains a reference that cannot be resolved: 'https://MYURL/soapWebService/api?wsdl'. Could not establish secure channel for SSL/TLS with authority 'myurl:8443'. The request was aborted: Could not create SSL/TLS secure channel.
I used the following code
var privCert = new X509Certificate2(#"c:\temp\test.p12", "testpass");
// privCert.Verify() => FALSE! WHY???
if (privCert.Verify()) Console.WriteLine("true");
else Console.WriteLine("false");
// create Web Request and set CLient Certificate für the authentication
HttpWebRequest request = CreateWebRequest();
request.ClientCertificates.Add(privCert);
// Create SOAP Message for PING Command
XmlDocument soapEnvelopeXml = new XmlDocument();
soapEnvelopeXml.LoadXml(#"<?xml version=""1.0"" encoding=""utf-8""?>
<soap:Envelope xmlns:soap=""http://www.w3.org/2003/05/soap-envelope"" xmlns:ws=""http://ws.soap.transfer.services.sedna.ser.com/"">
<soap:Header/>
<soap:Body>
<ws:ping>
<sessionUUID>something</sessionUUID>
</ws:ping>
</soap:Body>
</soap:Envelope>");
using (Stream stream = request.GetRequestStream())
{
soapEnvelopeXml.Save(stream);
}
Console.WriteLine("Credentials of request = " + request);
// Send Command to Webservice
try
{
using (WebResponse response = request.GetResponse())
{
using (StreamReader rd = new StreamReader(response.GetResponseStream()))
{
string soapResult = rd.ReadToEnd();
Console.WriteLine(soapResult);
}
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
Console.WriteLine("\nTaste!");
Console.ReadKey();
}
static HttpWebRequest CreateWebRequest()
{
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(#"https://doxapd01.zit.commerzbank.com:8443/soapWebService");
webRequest.Headers.Add(#"SOAP:Action");
webRequest.ContentType = "text/xml;charset=\"utf-8\"";
webRequest.Accept = "text/xml";
webRequest.Method = "POST";
return webRequest;
}
C# Code:
public static void CallWebService(string XmlText)
{
try
{
var _url = "https://nodeD1.test.webservices.amadeus.com/1ASIWMLFPNP";// "https://noded1.test.webservices.amadeus.com/1asiwmlfpnp";
var _action = "http://webservices.amadeus.com/fmptbq_14_3_1a";
XmlDocument soapEnvelopeXml = CreateSoapEnvelope(XmlText);
HttpWebRequest webRequest = CreateWebRequest(_url, _action);
webRequest = InsertSoapEnvelopeIntoWebRequest(soapEnvelopeXml, webRequest);
// begin async call to web request.
IAsyncResult asyncResult = webRequest.BeginGetResponse(null, null);
// suspend this thread until call is complete. You might want to
// do something usefull here like update your UI.
asyncResult.AsyncWaitHandle.WaitOne();
// get the response from the completed web request.
string soapResult;
using (WebResponse webResponse = webRequest.EndGetResponse(asyncResult))
{
using (StreamReader rd = new StreamReader(webResponse.GetResponseStream()))
{
soapResult = rd.ReadToEnd();
}
Console.Write(soapResult);
}
}
catch (WebException webex)
{
WebResponse errResp = webex.Response;
using (Stream respStream = errResp.GetResponseStream())
{
StreamReader reader = new StreamReader(respStream);
string text = reader.ReadToEnd();
}
}
}
private static HttpWebRequest CreateWebRequest(string url, string action)
{
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);
webRequest.Headers.Add("SOAPAction", action);
webRequest.ContentType = "text/xml;charset=\"utf-8\"";
webRequest.Accept = "text/xml";
webRequest.Method = "POST";
return webRequest;
}
private static XmlDocument CreateSoapEnvelope(string XmlText)
{
XmlDocument soapEnvelopeDocument = new XmlDocument();
soapEnvelopeDocument.LoadXml(string.Format(#"{0}",XmlText));
return soapEnvelopeDocument;
}
private static HttpWebRequest InsertSoapEnvelopeIntoWebRequest(XmlDocument soapEnvelopeXml, HttpWebRequest webRequest)
{
using (Stream stream = webRequest.GetRequestStream())
{
soapEnvelopeXml.Save(stream);
return webRequest;
}
}
Request:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:sec="http://xml.amadeus.com/2010/06/Security_v1" xmlns:typ="http://xml.amadeus.com/2010/06/Types_v1" xmlns:iat="http://www.iata.org/IATA/2007/00/IATA2010.1" xmlns:app="http://xml.amadeus.com/2010/06/AppMdw_CommonTypes_v3" xmlns:link="http://wsdl.amadeus.com/2010/06/ws/Link_v1" xmlns:ses="http://xml.amadeus.com/2010/06/Session_v3" xmlns:fmp="http://xml.amadeus.com/FMPTBQ_14_3_1A">
<soapenv:Header>
<add:MessageID xmlns:add="http://www.w3.org/2005/08/addressing">29e8e874-3033-dd52-6b75-a2da58e10291</add:MessageID>
<add:Action xmlns:add="http://www.w3.org/2005/08/addressing">http://webservices.amadeus.com/fmptbq_14_3_1A</add:Action>
<add:To xmlns:add="http://www.w3.org/2005/08/addressing">https://noded1.test.webservices.amadeus.com/1asiwmlfpnp</add:To>
<link:TransactionFlowLink xmlns:link="http://wsdl.amadeus.com/2010/06/ws/Link_v1"/>
<oas:Security xmlns:oas="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<oas:UsernameToken oas1:Id="UsernameToken-1" xmlns:oas1="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<oas:Username>WSPNPMLF</oas:Username>
<oas:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">bTEzbk5LNElzZw==</oas:Nonce>
<oas:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">5lkky7mUVRujQPg4blzfKi5dSyg=</oas:Password>
<oas1:Created>2017-12-15T13:43:34:532Z</oas1:Created>
</oas:UsernameToken>
</oas:Security>
<AMA_SecurityHostedUser xmlns="http://xml.amadeus.com/2010/06/Security_v1">
<UserID AgentDutyCode="SU" POS_Type="1" PseudoCityCode="BLRVS32CY" RequestorType="U"/>
</AMA_SecurityHostedUser>
</soapenv:Header>
<soapenv:Body>
<Fare_MasterPricerTravelBoardSearch>
<numberOfUnit>
<unitNumberDetail>
<numberOfUnits>1</numberOfUnits>
<typeOfUnit>PX</typeOfUnit>
</unitNumberDetail>
<unitNumberDetail>
<numberOfUnits>250</numberOfUnits>
<typeOfUnit>RC</typeOfUnit>
</unitNumberDetail>
</numberOfUnit>
<paxReference>
<ptc>ADT</ptc>
<traveller>
<ref>1</ref>
</traveller>
</paxReference>
<fareOptions>
<pricingTickInfo>
<pricingTicketing>
<priceType>RP</priceType>
<priceType>RU</priceType>
<priceType>TAC</priceType>
<priceType>ET</priceType>
</pricingTicketing>
</pricingTickInfo>
</fareOptions>
<travelFlightInfo>
<cabinId>
<cabinQualifier>RC</cabinQualifier>
<cabin>Y</cabin>
</cabinId>
</travelFlightInfo>
<itinerary>
<requestedSegmentRef>
<segRef>1</segRef>
</requestedSegmentRef>
<departureLocalization>
<depMultiCity>
<locationId>DEL</locationId>
</depMultiCity>
</departureLocalization>
<arrivalLocalization>
<arrivalMultiCity>
<locationId>BOM</locationId>
</arrivalMultiCity>
</arrivalLocalization>
<timeDetails>
<firstDateTimeDetail>
<timeQualifier>TD</timeQualifier>
<date>201217</date>
<time>0000</time>
<timeWindow></timeWindow>
</firstDateTimeDetail>
</timeDetails>
</itinerary>
<itinerary>
<requestedSegmentRef>
<segRef>1</segRef>
</requestedSegmentRef>
<departureLocalization>
<depMultiCity>
<locationId>BOM</locationId>
</depMultiCity>
</departureLocalization>
<arrivalLocalization>
<arrivalMultiCity>
<locationId>DEL</locationId>
</arrivalMultiCity>
</arrivalLocalization>
<timeDetails>
<firstDateTimeDetail>
<timeQualifier>TD</timeQualifier>
<date>251217</date>
<time>0000</time>
<timeWindow></timeWindow>
</firstDateTimeDetail>
</timeDetails>
</itinerary>
</Fare_MasterPricerTravelBoardSearch>
</soapenv:Body>
</soapenv:Envelope>
Response:
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<soap:Fault>
<faultcode>soap:Client</faultcode>
<faultstring>12|Presentation|soap message header incorrect</faultstring>
<faultactor>SI:muxDZ2</faultactor>
</soap:Fault>
</soap:Body>
</soap:Envelope>
When the same request is passed using SoapUI im getting response but when C# Code is used im getting the above response.. if any one have implemented Amadeus Soap4.0 API in C# please help.
Maybe you have setup SoapUI to perform additional actions on the request payload (thus the request is not the same) ?
I would advise to create a proxy class from the given WSDL. While this proxy class doesn't support Nonce by default, it's extensible. check out WCF: Adding Nonce to UsernameToken
Now the 12 error code you get could also derive from other things.... Like for example I don't see your <Session /> element there (unless this represents a stateless request?)
I have the following program written in C# to consume a web service.
class Program
{
static void Main(string[] args)
{
Program obj = new Program();
obj.InvokeService();
}
public HttpWebRequest CreateSOAPWebRequest()
{
HttpWebRequest Req =
(HttpWebRequest)WebRequest.Create(#"https://MyWebService");
Req.ContentType = "text/xml;charset=\"utf-8\"";
Req.Accept = "text/xml";
Req.Method = "POST";
return Req;
}
public void InvokeService()
{
HttpWebRequest request = CreateSOAPWebRequest();
XmlDocument SOAPReqBody = new XmlDocument();
SOAPReqBody.LoadXml(#"<?xml version=""1.0"" encoding=""utf-8""?>
<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/""
xmlns:soapenc=""http://schemas.xmlsoap.org/soap/encoding/"">
<soapenv:Header/>
<soapenv:Body>
<Content>..... </Content>
</soapenv:Body>
</soapenv:Envelope>");
using (Stream stream = request.GetRequestStream())
{
SOAPReqBody.Save(stream);
}
using (WebResponse Serviceres = request.GetResponse())
{
using (StreamReader rd = new
StreamReader(Serviceres.GetResponseStream()))
{
var ServiceResult = rd.ReadToEnd();
Console.WriteLine(ServiceResult);
Console.ReadLine();
}
}
}
}
I now want to attach the WSDL to this soap request.
What I have is a .wsdl file. I tried this SOAP request using "SOAP UI" and it worked , I received the response.
It seems like I need to specify the method in the SOAP header and I am not able to do that. I can only place the .WSDL file somewhere in the project folder.
Can someone help me to get the correct response ?
In my web project, I am using http request and response for access https payment site. But when I call getresponse() function, it return "Precondition failed (412)" error.
HttpWebRequest paymentRequest = (HttpWebRequest)WebRequest.Create("https://xxxxxx/authorize");
Uri uri = new Uri("https://xxxxxx/authorize");
NetworkCredential netCredential = new NetworkCredential("XXXXXXXXX", "XXXXXXXXX");
paymentRequest.Credentials = netCredential.GetCredential(uri, "Basic");
paymentRequest.PreAuthenticate = true;
byte[] Data = System.Text.Encoding.ASCII.GetBytes(sXMLTemplate);
paymentRequest.Method = "POST";
paymentRequest.Headers.Add("MIME-Version", "1.0");
paymentRequest.Headers.Add("Request-number", "1");
paymentRequest.Headers.Add("Document-type", "Request");
paymentRequest.Headers.Add("Content-transfer-encoding", "application/xml");
paymentRequest.ContentType = "application/xml";
paymentRequest.ContentLength = Data.Length;
paymentRequest.KeepAlive = true;
Stream streamWriter = paymentRequest.GetRequestStream();
streamWriter.Write(Data, 0, Data.Length);
streamWriter.Close();
HttpWebResponse paymentResponse = (HttpWebResponse)paymentRequest.GetResponse();
Stream responseStream = paymentResponse.GetResponseStream();
reader = new XmlTextReader(responseStream);
How to fix this error?
Please check if XML data you are POSTing validates successfully and there is no missing XML elements if XML schema is enforced
Have a look at the valid content-transfer-encodings.
BASE64
8BIT
7BIT
BINARY
QUOTED-PRINTABLE
application/something is for Content-Type, not encoding.
For more info, look at the specs here:
http://www.w3.org/Protocols/rfc1341/5_Content-Transfer-Encoding.html
What I do Think you're after is this:
paymentRequest.Headers.Add("Content-type", "application/xml");
or simply:
paymentRequest.ContentType = "application/xml";