I am trying to write some unit tests for a SOAP Router that I have created and need to sent a Message to the system under test that has specific values in the body that are being checked.
I am able hit the system under test but the result is always false.
Below is the code that I am using to try and build up the message
public Message CreateValidGetProposalListMessage()
{
var sb = new StringBuilder();
sb.AppendLine("<soapenv:Envelope xmlns:exsl=\"http://exslt.org/common\" xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">");
sb.AppendLine(" <s:Header xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\">");
sb.AppendLine(" <To s:mustUnderstand=\"1\" xmlns=\"http://schemas.microsoft.com/ws/2005/05/addressing/none\">https://localhost:44321/routingService</To>");
sb.AppendLine(" <Action s:mustUnderstand=\"1\" xmlns=\"http://schemas.microsoft.com/ws/2005/05/addressing/none\">getList</Action>");
sb.AppendLine(" </s:Header>");
sb.AppendLine(" <soapenv:Body>");
sb.AppendLine(" <getList xmlns=\"http://xxx">");
sb.AppendLine(" <code>xxx</code>");
sb.AppendLine(" </getList>");
sb.AppendLine(" </soapenv:Body>");
sb.AppendLine("</soapenv:Envelope>");
var ms = new MemoryStream(Encoding.UTF8.GetBytes(sb.ToString()));
var xdr = XmlDictionaryReader.CreateTextReader(ms, new XmlDictionaryReaderQuotas());
var newMessage = Message.CreateMessage(xdr, int.MaxValue, MessageVersion.Soap11);
return newMessage;
}
With this code the message is created, however the body always returns like this
<soapenv:Body>... stream ...</soapenv:Body>
I have a total of 9 tests that I need to write to complete the test conditions and am failing on the first because the body of the message is not being written.
I appreciate this might not be the correct approach and would be grateful if anyone could help me get this right.
I have also seen this but cannot get this to work either WCF message body showing <s:Body>... stream ...</s:Body> after modification
thanks
Simon
After creating a message using the CreateMessage(XmlReader, Int32, MessageVersion) method, you can use the GetBody method to read the body of the message.
For more information about CreateMessage,Please refer to this link.
You can also get the message content through System.Xml.XmlWriter after getting the message:
MessageBuffer buffer = newMessage.CreateBufferedCopy(Int32.MaxValue);
Message msg = buffer.CreateMessage();
StringBuilder sbb = new StringBuilder();
using (System.Xml.XmlWriter xx = System.Xml.XmlWriter.Create(sbb))
{
msg.WriteMessage(xx);
xx.Close();
}
Console.WriteLine(sbb);
The result of running:
UPDATE
Here is my Demo:
public void BeforeSendReply(ref Message reply, object correlationState)
{
var sb = new StringBuilder();
sb.AppendLine("<soapenv:Envelope xmlns:exsl=\"http://exslt.org/common\" xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">");
sb.AppendLine(" <s:Header xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\">");
sb.AppendLine(" <To s:mustUnderstand=\"1\" xmlns=\"http://schemas.microsoft.com/ws/2005/05/addressing/none\">https://localhost:44321/routingService</To>");
sb.AppendLine(" <Action s:mustUnderstand=\"1\" xmlns=\"http://schemas.microsoft.com/ws/2005/05/addressing/none\">getList</Action>");
sb.AppendLine(" </s:Header>");
sb.AppendLine(" <soapenv:Body>");
sb.AppendLine(" <getList xmlns=\"http://xxx\" > ");
sb.AppendLine(" <code>xxx</code>");
sb.AppendLine(" </getList>");
sb.AppendLine(" </soapenv:Body>");
sb.AppendLine("</soapenv:Envelope>");
var ms = new MemoryStream(Encoding.UTF8.GetBytes(sb.ToString()));
var xdr = XmlDictionaryReader.CreateTextReader(ms, new XmlDictionaryReaderQuotas());
var newMessage = Message.CreateMessage(xdr, int.MaxValue, MessageVersion.Soap11);
MessageBuffer messageBuffer = newMessage.CreateBufferedCopy(int.MaxValue);
Message message = messageBuffer.CreateMessage();
reply = message;
}
In the gif, you can see that the client received the Message I customized on the server.
Related
I don't think this is a code issue, but we have a list of hundreds of addresses to process. Some return data and we are able to get Long and Lat but most return (401) UnAuthorized errors. What would cause this to happen? We have tried passing Host Headers and everything else, the REST API seems to work better in our development environment but throws way more errors when deployed to our Job Server. Any help on this issue will be greatly appreciated. We would like to understand why some calls work and others don't, we pass the same apiKey each time so this is really confusing. Thanks
Here is a code snippet using c# (Work in progress):
//GET THE LATITUDE AND LONGITUDE BASED OFF THE PHYSICAL ADDRESS
String clientAddress = clientRow["home_address"].ToString() + ", " + clientRow["home_city"].ToString() + ", " + clientRow["home_state"].ToString() + ", " + clientRow["home_zip"].ToString();
Logger.Debug("CLIENT ADDRESS: {0}", clientAddress);
String geocoderUri = "https://geocode.search.hereapi.com/v1/geocode?q=" + clientAddress + "&apiKey=xxxxxxxxxxxxxxxxxxxxx"; //KEY REMOVED FOR POSTING ON STACK OVERFLOW
var syncClient = new WebClient();
var content = syncClient.DownloadString(geocoderUri);
//CREATE THE JSON SERIALIZER AND PARSE OUR RESPONSE
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(AddressData));
using (var ms = new MemoryStream(Encoding.Unicode.GetBytes(content)))
{
var addressData = (AddressData)serializer.ReadObject(ms);
if (addressData.items.Count() > 0)
{
//INSERT THE LATITUDE AND LONGITUDE IN DB
String sLat = addressData.items[0].position.lat.ToString();
String sLong = addressData.items[0].position.lng.ToString();
Logger.Debug("CLIENT GEOLOCATION - Longitude: {0} Latitude: {1}", sLong, sLat);
insertLatLong(sLat, sLong, clientRow["clientID"].ToString(), 1);
}
}
Would you please try to use RestSharp lib for rest api?
Please see below sample code.
var client = new RestClient("https://geocode.search.hereapi.com/v1/geocode?q="+ clientAddress);
client.Timeout = -1;
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer YOUR TOKEN");
IRestResponse response = client.Execute(request);
Console.WriteLine(response.Content);
This code runs fine in my windows form application using .net framework 4.6.2 but when I go to make it a console application so it can be ran from the task scheduler I get no results. I think I am losing something in translation.
RestClient restClient = new RestClient("https://api.vault.com");
string refreshToken = #"abc";
string encodedClientIdSecret = Base64Encode("AP-123");
string responseStr = "";
string url = "/v1/OAuth";
dynamic jsonObj = "";
RestRequest request = new RestRequest(url, Method.POST);
request.AddHeader("Authorization", encodedClientIdSecret);
request.AddParameter("grant_type", "refresh_token");
request.AddParameter("refresh_token", refreshToken);
IRestResponse response;
restClient.Execute(request);
response = restClient.Execute(request);
Console.WriteLine(response.Content + " || " + encodedClientIdSecret);
Console.ReadKey();
jsonObj = JsonConvert.DeserializeObject(response.Content);
responseStr = jsonObj.access_token;
return responseStr;
It basically tells me the value cannot be null, and when I look at response.Content I get nothing and the status code comes back as "0". Any thoughts?
Just added:
//Required For SSL/TLS Error Start
ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
//Required For SSL/TLS Error End
and I got my results. Hope this helps someone else!
This is a request to GoCardless test API from a Dynamics CRM plugin. I receive "The request was aborted: Could not create SSL/TLS secure channel." error. It only happens on the first request after some time without sending one. If I send it again, it will be OK. I would appreciate a lot your help.
Here is my code:
//I have tried all the following lines in comment without success
//ServicePointManager.ServerCertificateValidationCallback += ValidateRemoteCertificate;
//ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;
//ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
//ServicePointManager.Expect100Continue = true;
//ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
// Create a new WebClient instance.
string baseURL = "https://api-sandbox.gocardless.com/";
WebClient client = new WebClient();
client.Headers.Add("Content-Type", "application/json");
client.Headers.Add("Authorization", "Bearer " + t);
client.Headers.Add("GoCardless-Version", "2015-07-06");
client.Headers.Add("Accept", "application/json");
Customers model = new Customers();
customer.country_code = "GB";
model.customers = customer;
MemoryStream stream1 = new MemoryStream();
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(Customers));
ser.WriteObject(stream1, model);
stream1.Position = 0;
StreamReader sr = new StreamReader(stream1);
// Apply ASCII Encoding to obtain the string as a byte array.
byte[] byteArray = Encoding.ASCII.GetBytes(sr.ReadToEnd());
ReturnedCustomers result = new ReturnedCustomers();
//Upload the input string using the HTTP 1.0 POST method.
try
{
byte[] responseArray = client.UploadData(baseURL + "customers", "POST", byteArray);
string responseText = Encoding.ASCII.GetString(responseArray);
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(ReturnedCustomers));
using (Stream s = GenerateStreamFromString(responseText))
{
result = (ReturnedCustomers)serializer.ReadObject(s);
}
}
catch (WebException exception)
{
}
From the Microsoft documentation (https://msdn.microsoft.com/en-us/library/gg334752.aspx) are the following limitations:
Only the HTTP and HTTPS protocols are allowed.
Access to localhost (loopback) is not permitted.
IP addresses cannot be used. You must use a named web address that requires DNS name resolution.
Anonymous authentication is supported and recommended.
5.There is no provision for prompting the logged on user for credentials or saving those credentials.
The error may be due to seguneti things:
The certificate is invalid
The certification authority is not public
Could you check what is the value of ServicePointManager.Expect100Continue and ServicePointManager.SecurityProtocol attributes in your environment?
I would like to upload a file to QuickBooks Online using IDS V3.
I followed the steps described here
https://developer.intuit.com/docs/0025_quickbooksapi/0050_data_services/020_key_concepts/attachments.
Here is my source code
URL url = new URL("https://quickbooks.api.intuit.com/v3/company/My_company_ID/upload");
HttpURLConnection request = (HttpURLConnection) url.openConnection();
request.setDoOutput(true);
request.setRequestMethod("POST");
HttpParameters para = new HttpParameters();
//String status = URLEncoder.encode("中 文","utf-8").replaceAll("\\+", "%20");
//para.put("status", status);
String boundary = "---------------------------37531613912423";
//String content = "--"+boundary+"\r\nContent-Disposition: form-data; name=\"status\"\r\n\r\n";
String pic = "\r\n--"+boundary+"\r\nContent-Disposition: form-data; name=\"pic\"; filename=\"postpic.gif\"\r\nContent-Type: image/gif\r\n\r\n";
byte[] end_data = ("\r\n--" + boundary + "--\r\n").getBytes();
File f = new File("/Users/cnanfack/Documents/oml_map1.gif");
FileInputStream stream = new FileInputStream(f);
byte[] file = new byte[(int)f.length()];
stream.read(file);
String lineEnd = "\r\n";
String header = "Content-Disposition: form-data; name=\"file_metadata_0\""+lineEnd
+"Content-Type: application/xml; charset=UTF-8"+lineEnd
+"Content-Transfer-Encoding: 8bit"+lineEnd;
String attachable = header+"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><Attachable xmlns=\"http://schema.intuit.com/finance/v3\" domain=\"QBO\" sparse=\"false\">"
+"<EntityRef type=\"Bill\">285</EntityRef>"
+"<Size>4099</Size>"
+"<ContentType>image/gif</ContentType>"
+"<FileName>postpic.gif</FileName>"
+"</Attachable>";
request.setRequestProperty("Content-Type", "multipart/form-data; boundary="+boundary);
//request.setRequestProperty("Content-Length", String.valueOf(boundary.getBytes().length+"test".getBytes().length+pic.getBytes().length+f.length()+end_data.length));
//consumer.setAdditionalParameters(para);
consumer.sign(request);
OutputStream ot = request.getOutputStream();
ot.write(end_data);
ot.write(attachable.getBytes());
ot.write(end_data);
//ot.write(status.getBytes());
ot.write(pic.getBytes());
ot.write("Content-Transfer-Encoding: binary\r\n\r\n".getBytes());
ot.write(file);
ot.write(end_data);
ot.flush();
ot.close();
System.err.println("Sending request...");
request.connect();
System.err.println("Response: " + request.getResponseCode() + " "
+ request.getResponseMessage());
BufferedReader reader =new BufferedReader(new InputStreamReader(request.getInputStream()));
String b = null;
while((b = reader.readLine())!=null){
System.err.println(b);
}
The returned result:
Response: 200 OK
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><IntuitResponse xmlns="http://schema.intuit.com/finance/v3" time="2013-11-10T20:24:27.823-08:00"/>
But I don't see the file on Quickbooks Online.
Maybe I miss something. Can someone help me?
Thank you in advance
I had tried this Upload endpoint call using Java Devkit. It is working fine. PFB details.
- Request URI : https://quickbooks.api.intuit.com/v3/company/688779980/upload? Http
- Method : POST Content-Disposition: form-data; name="file_metadata_2bddf"
- Content-Type: application/xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Attachable xmlns="http://schema.intuit.com/finance/v3">
<FileName>images.jpg</FileName>
<ContentType>image/jpeg</ContentType>
<Lat>25.293112341223</Lat>
<Long>-21.3253249834</Long>
<PlaceName>Fake Place</PlaceName>
<Note>Attachable note 900a49e1</Note>
<Tag>Attachable tag 900a49e1</Tag>
</Attachable>
Response XML
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<IntuitResponse xmlns="http://schema.intuit.com/finance/v3" time="2013-11-12T05:58:25.296-08:00">
<AttachableResponse>
<Attachable domain="QBO" sparse="false">
<Id>100000000000543524</Id>
<SyncToken>0</SyncToken>
<MetaData>
<CreateTime>2013-11-12T05:58:26-08:00</CreateTime>
<LastUpdatedTime>2013-11-12T05:58:26-08:00</LastUpdatedTime>
</MetaData>
<FileName>images.jpg</FileName>
<FileAccessUri>/v3/company/688779980/download/100000000000543524</FileAccessUri>
<TempDownloadUri>https://intuit-qbo-prod-19.s3.amazonaws.com/688779980%2Fattachments%2Fimages-1384264705362.jpg?Expires=1384265606&AWSAccessKeyId=AKIAJEXDXKNYCBUNCCCQ&Signature=ESZPzeO%2B5YWxw8VOWMVMBRnvIdw%3D</TempDownloadUri>
<Size>58616</Size>
<ContentType>image/jpeg</ContentType>
<Lat>25.293112341223</Lat>
<Long>-21.3253249834</Long>
<PlaceName>Fake Place</PlaceName>
<Note>Attachable note 8219e79a</Note>
<Tag>Attachable tag 8219e79a</Tag>
<ThumbnailFileAccessUri>/v3/company/688779980/attachable-thumbnail/100000000000543524</ThumbnailFileAccessUri>
</Attachable>
</AttachableResponse>
</IntuitResponse>
From the ThumnailFileAccessUri property I got the following attachment URI which I had used for Download endpoint.
/v3/company/688779980/attachable-thumbnail/100000000000543524
Download Endpoint(GET)-
https://quickbooks.api.intuit.com/v3/company/688779980/download/100000000000543521
JAVA/.Net SDK download link - https://developer.intuit.com/docs/0025_quickbooksapi/0055_devkits
Hope it will be useful.
EDIT- Adding Java code snippet
public static void executeUploadForImageFilePoc(DataService service) throws ParseException, FMSException, FileNotFoundException {
System.out.println("executeUploadForImageFile");
String uuid = UUID.randomUUID().toString().substring(0, 8);
Attachable attachable1 = new Attachable();
//attachable.setSize(new Long("34234"));
attachable1.setLat("25.293112341223");
attachable1.setLong("-21.3253249834");
attachable1.setPlaceName("Fake Place");
attachable1.setNote("Attachable note " + uuid);
attachable1.setTag("Attachable tag " + uuid);
Attachable attachable = attachable1;
attachable.setFileName("images.jpg");
attachable.setContentType("image/jpeg");
File file = new File("C:\\images_new.jpg");
InputStream in = new FileInputStream(file);
//Upload endpoint call
Attachable attachableOutput = service.upload(attachable, in);
//Check return XML
attachable.getFileAccessUri();
System.out.println(attachableOutput.getFileAccessUri());
System.out.println(attachableOutput.getFileName());
//Download endpoint call
InputStream output = service.download(attachableOutput);
try {
BufferedImage bImageFromConvert = ImageIO.read(output);
ImageIO.write(bImageFromConvert, "jpg", new File("C:\\images_new_manas.jpg"));
} catch (IOException e) {
throw new FMSException("Error while reading the upload file.", e);
}
}
Thanks
I have a working code in dotnet. See if it works for you:
DataService.DataService commonServiceQBO= new DataService.DataService(qboContextoAuth);
string imagePath = string.Concat(AppDomain.CurrentDomain.BaseDirectory, "\\", "Services\\Resource\\image.jpg");
System.IO.FileInfo file = new System.IO.FileInfo(imagePath);
Attachable attachable = new Attachable();
attachable.AttachableRef = new AttachableRef[1];
attachable.AttachableRef[0].EntityRef = new ReferenceType();
attachable.AttachableRef[0].EntityRef.type = "Bill";
attachable.AttachableRef[0].EntityRef.Value = "12";
attachable.Lat = "25.293112341223";
attachable.Long = "-21.3253249834";
attachable.PlaceName = "Fake Place";
attachable.Note = "Attachable note123 ";
attachable.Tag = "Attachable tag123 ";
using (System.IO.FileStream fs = file.OpenRead())
{
attachable.ContentType = "image/jpeg";
attachable.FileName = file.Name;
Attachable attachableUploaded = commonServiceQBO.Upload(attachable, fs);
}
For download use:
byte[] responseByte = service.Download(attachableUploaded);
I am working on Adobe Echo sign,I have downloaded the sample code from their website, I am using this sample code for sendingdocument, it has some code missing in sendDocument method so I have changed it. It's giving SoapHeader Exception,with nothing in InnerException,
{"apiActionId=XHZI4WF4BV693YS"}
below is my code of sending document
public static void sendDocument(string apiKey, string fileName, string recipient)
{
ES = new EchoSignDocumentService16();
FileStream file = File.OpenRead(fileName);
secure.echosign.com.FileInfo[] fileInfos = new secure.echosign.com.FileInfo[1];
fileInfos[0] = new secure.echosign.com.FileInfo(fileName, null, file);
SenderInfo senderInfo = null;
string[] recipients = new string[1];
recipients[0] = recipient;
DocumentCreationInfo documentInfo = new DocumentCreationInfo(
recipients,
"Test from SOAP: " + fileName,
"This is neat.",
fileInfos,
SignatureType.ESIGN,
SignatureFlow.SENDER_SIGNATURE_NOT_REQUIRED
);
DocumentKey[] documentKeys;
senderInfo = new SenderInfo(recipient, "password", "APIKEY");
documentKeys = ES.sendDocument(apiKey, senderInfo, documentInfo);
Console.WriteLine("Document key is: " + documentKeys[0].documentKey);
}
its giving exception on this line
documentKeys = ES.sendDocument(apiKey, senderInfo, documentInfo);
Can anyone suggest some sample code of Adobe Echo Sign?
On the account page of your login there is an API log you can check. If you check the log entry for your request you may find more information there.
I can't see anything immediately wrong with your code however the EchoSign API guide says that the 'tos' field is deprecated and that the recipients field should be used instead. Helpfully this means you can't use the paramaterised constructor. Try creating your document creation info as such (this is C# but if you need Java it should be straightforward to figure out):
RecipientInfo[] recipientInfo = new RecipientInfo[1];
recipientInfo[0] = new RecipientInfo
{
email = "recipient",
role = RecipientRole.SIGNER,
roleSpecified = true
};
DocumentCreationInfo documentCreationInfo = new DocumentCreationInfo
{
recipients = recipientInfo,
name = "Test from SOAP: " + fileName,
message = "This is neat.",
fileInfos = fileInfos,
signatureType = SignatureType.ESIGN,
signatureFlow = SignatureFlow.SENDER_SIGNATURE_NOT_REQUIRED
};
Note that when using the recipientInfo array it seems that the roleSpecified field must be set to true. This little field tripped me up for ages and I was receiving errors similar to yours.