Customize SOAP request send from Windows 8 application - web-services

I am consuming a WSDL in a Windows 8 app. I need to customize the SOAP request like
New SOAP Request:
</ns0:Header>
<ns0:Body>
<ns0:Request xmlns:ns0="http://www.ABC.co.il/2004/01/RetrieveEntityDetails/EntityDetailsRequest">
</ns0:Request></ns0:Body></ns0:Envelope>
Current SOAP Request:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
</s:Header>
<s:Body>
<RetrieveEntityDetailsXPOP_XmlRequest xmlns="http://tempuri.org/">
<RetrieveEntityDetailsXPOP_Xml xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<requestDoc>
</requestDoc>
</RetrieveEntityDetailsXPOP_Xml>
</RetrieveEntityDetailsXPOP_XmlRequest>
</s:Body>
</s:Envelope>
How will I change the namespace and set a request tag inside the body tag.
Code:
Client = new EAI_RetrieveEntityDetailsXP_ServiceSoapClient();
Client.RetrieveEntityDetailsXPOP_XmlCompleted += Client_RetrieveEntityDetailsXPOP_XmlCompleted;
XElement requestData = GetRequestData();
using (new OperationContextScope(Client.InnerChannel))
{
// Create a custom soap header
var msgHeader = MessageHeader.CreateHeader("myCustomHeader", string.Empty, "myValue");
// Add the header into request message
OperationContext.Current.OutgoingMessageHeaders.Add(msgHeader);
Client.RetrieveEntityDetailsXPOP_XmlAsync(requestData);
}

I have actually used HttpCleint to call this service by using following code. Using this we can generate the SOAP request as desired.
string soapString = ConstructSoapRequest();
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Add("SOAPAction", SOAPActionUri);
var content = new StringContent(soapString, Encoding.UTF8, "text/xml");
using (var response = await client.PostAsync(Uri, content))
{
var soapResponse = await response.Content.ReadAsStringAsync();
return soapResponse;
}
}
private string ConstructSoapRequest()
{
return String.Format(#"<ns0:Envelope xmlns:ns0='http://www.cellcom.co.il/2004/01/std-headers'>
<ns0:Header>
</ns0:Header>
<ns0:Body>
<ns0:Request xmlns:ns0='http://www.cellcom.co.il/2004/01/RetrieveEntityDetails/EntityDetailsRequest'>
</ns0:Request></ns0:Body></ns0:Envelope>", 100);
}

Related

Using Httpclient for send SOAP request In Asp.net Core

Im using Asp.net Core, for calling an asmx service which has 4 methods and i want to call one of them by the name: Verify method, i do this steps:
1-Create realted SOAP:
private XmlDocument CreateSoapEnvelope(PayVM payModel)
{
XmlDocument soapEnvelop = new XmlDocument();
string requiredXML = string.Format(#"<SOAP-ENV:Envelope xmlns:SOAP-ENV=""http://schemas.xmlsoap.org/soap/envelope/"" xmlns:xsi=""http://www.w3.org/1999/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/1999/XMLSchema""><SOAP-ENV:Body><verifyTransaction xmlns=""http://tempuri.org/""> <String_1 xsi:type=""xsd:string"">{0}</String_1><String_2 xsi:type=""xsd:string"">{1}</String_2></verifyTransaction></SOAP-ENV:Body></SOAP-ENV:Envelope>", payModel.ReNO, payModel.MID);
soapEnvelop.LoadXml(requiredXML);
return soapEnvelop;
}
2-create the HttpClient and send my request:
XmlDocument soapRequest = CreateSoapEnvelope(iPGVerifyResultModel);
using (var client = new HttpClient())
{
var request = new HttpRequestMessage()
{
RequestUri = new Uri("relatedUri/ServiceName.asmx"),
Method = HttpMethod.Post
};
request.Content = new StringContent(soapRequest.ToString(), Encoding.UTF8, "text/xml");
request.Headers.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("text/xml"));
request.Content.Headers.ContentType = new MediaTypeHeaderValue("text/xml");
request.Headers.Add("SOAPAction", "Verify"); //I want to call this method
HttpResponseMessage response = client.SendAsync(request).Result;
if (!response.IsSuccessStatusCode)
{
throw new Exception();
}
Task<Stream> streamTask = response.Content.ReadAsStreamAsync();
Stream stream = streamTask.Result;
var sr = new StreamReader(stream);
var soapResponse = XDocument.Load(sr);
//do some other stuff...
}
but i didn't result, i try uses service by same parameters with Soap UI and the service work properly, but in my way i got StatusCode: 400 what is the problem?

Windows.Web.HttpClient: Cookies will not be sent

I send a HTTP Get Request with a Basic Authentification to the Login-Endpoint of the Host:
request = new HttpRequestMessage();
// Configuration Item: Login URL Suffix
request.RequestUri = new Uri(string.Format("https://{0}/{1}", Host, loginSuffix));
request.Method = Windows.Web.Http.HttpMethod.Get;
var info = User + ":" + Password;
var token = Convert.ToBase64String(Encoding.UTF8.GetBytes(info));
request.Headers.Authorization = new HttpCredentialsHeaderValue("Basic", token);
_httpClient = CreateHttpClient(ref cookieManager);
response = await _httpClient.SendRequestAsync(request, HttpCompletionOption.ResponseContentRead);
response.EnsureSuccessStatusCode();
responseBodyAsText = await response.Content.ReadAsStringAsync();
The HttpClient is created with a Filter, to set Cookies later:
private HttpClient CreateHttpClient(ref HttpCookieManager _cookieManager)
{
HttpBaseProtocolFilter _filter = new HttpBaseProtocolFilter();
HttpClient _httpClient = new Windows.Web.Http.HttpClient(_filter);
_cookieManager = _filter.CookieManager;
return _httpClient;
}
From the Response the SET-COOKIE Header can be read.
string[] Queries;
response.Headers.TryGetValue("Set-Cookie", out tmpString);
if (tmpString != null)
Queries = tmpString.Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries);
I´m looking for a Cookie with a defined Name (CookieKeyName), which will be set in the next Request.
foreach (var query in Queries)
{
if (query.Contains(CookieKeyName))
{
staticCookieKey = query.Substring(0, query.IndexOf("="));
staticCookieValue = query.Substring(query.IndexOf("=") + 1);
}
}
I would expect, that the HttpClient will use the received Set-Cookie in the response for this URL as Cookie in every following Request automatically.
I´m preparing the next Request and setting the Cookie by myself:
request.RequestUri = new Uri(string.Format("https://{0}/qcbin", Host));
request.Method = Windows.Web.Http.HttpMethod.Get;
HttpCookie _cookie = new Windows.Web.Http.HttpCookie(staticCookieKey, Host, "/");
_cookie.Value = staticCookieValue;
bool replaced = cookieManager.SetCookie(_cookie);
The following Sending of the Requests provides to a Web Exception 401, because the Server expects for this URL the previously in the Response received Cookie.
response = await _httpClient.SendRequestAsync(request, HttpCompletionOption.ResponseContentRead);
response.EnsureSuccessStatusCode();
responseBodyAsText = await response.Content.ReadAsStringAsync();
Looking with Fiddler on the Line, the second Request contains no Cookie Header. Even Setting of the Cookie in CookieManager nor the proceeding of the Set-Cookie i the first Response by the HttpClient is working.
Hint: The length of the value of the Cookies is about 6000 chars (coming from a IBM Data Power).
Thank you in advance for help.

Issue invoking web service within websphere 6.1 environment

I'm trying to invoke a SOAP web service from within WebSphere 6.1. I can run the code fine using Apache Tomcat 6.0.36 runtime. However, with WebSphere 6.1, I get the following error:
Jan 5, 2015 7:19:23 PM com.ibm.ws.ssl.config.SSLConfigManager INFO:ssl.disable.url.hostname.verification.CWPKI0027I
Jan 5, 2015 7:19:24 PM com.ibm.ws.channel.framework.impl.WSChannelFrameworkImpl AUDIT: chain.started
Jan 5, 2015 7:19:25 PM com.ibm.ws.webservices.engine.PivotHandlerWrapper invoke WARNING:
WSWS3734W: Warning: Exception caught from invocation to com.ibm.ws.webservices.engine.transport.http.HTTPSender:
WebServicesFault faultCode:
HTTP faultString: ( 401 ) Unauthorized faultActor: http://server.customer.com:80
faultDetail: null:
WSWS3192E: Error: return code: ( 401 ) Unauthorized
Here's the code I'm running, which works fine in Apache Tomcat:
public class Test {
public void submitOrder()
{
try {
// Create SOAP Connection
SOAPConnectionFactory soapConnectionFactory = SOAPConnectionFactory.newInstance();
SOAPConnection soapConnection = soapConnectionFactory.createConnection();
// Send SOAP Message to SOAP Server
String url = "http://server.customer.com/serviceEndpoint";
SOAPMessage soapResponse = soapConnection.call(createSOAPRequest(), url);
// Process the SOAP Response
printSOAPResponse(soapResponse);
soapConnection.close();
} catch (Exception e) {
System.err.println("Error occurred while sending SOAP Request to Server");
e.printStackTrace();
}
}
private static SOAPMessage createSOAPRequest() throws Exception {
MessageFactory messageFactory = MessageFactory.newInstance();
SOAPMessage soapMessage = messageFactory.createMessage();
MimeHeaders hd = soapMessage.getMimeHeaders();
String username = "xxxxx";
String password = "xxxxx";
byte [] auth = (username+":"+password).getBytes();
String authorization = new String ( Base64.encodeBase64(auth) );
System.out.println ( "authorization = " + authorization );
hd.addHeader("Authorization", "Basic " + authorization);
SOAPPart soapPart = soapMessage.getSOAPPart();
// SOAP Envelope
SOAPEnvelope envelope = soapPart.getEnvelope();
// SOAP Body
SOAPBody soapBody = envelope.getBody();
SOAPElement ordersElem = soapBody.addChildElement("Orders");
// Need to add two attributes to this node!
SOAPElement orderElem = ordersElem.addChildElement("Order");
Name codeAttributeName = envelope.createName("code");
orderElem.addAttribute(codeAttributeName, "00001");
Name timeAttributeName = envelope.createName("time");
orderElem.addAttribute(timeAttributeName, "2015-01-04 12:00:00 PM");
SOAPElement salesOrderConfElem = orderElem.addChildElement("SalesOrderConfirmationCode");
salesOrderConfElem.addTextNode("16041");
SOAPElement statusElem = orderElem.addChildElement("Status");
Name statusCodeAttributeName = envelope.createName("code");
statusElem.addAttribute(statusCodeAttributeName, "COMPLETE");
SOAPElement entriesElem = orderElem.addChildElement("Entries");
SOAPElement entryElem = entriesElem.addChildElement("Entry");
SOAPElement entryNumElem = entryElem.addChildElement("EntryNumber");
entryNumElem.addTextNode("1");
SOAPElement productElem = entryElem.addChildElement("ProductCode");
productElem.addTextNode("738053571");
SOAPElement qtyElem = entryElem.addChildElement("Quantity");
qtyElem.addTextNode("1");
SOAPElement shippedElem = entryElem.addChildElement("Shipped");
shippedElem.addTextNode("1");
SOAPElement backOrderElem = entryElem.addChildElement("Backordered");
backOrderElem.addTextNode("1");
MimeHeaders headers = soapMessage.getMimeHeaders();
headers.addHeader("SOAPAction", "http://sap.com/xi/WebService/soap1.1");
soapMessage.saveChanges();
/* Print the request message */
System.out.print("Request SOAP Message = ");
soapMessage.writeTo(System.out);
System.out.println();
return soapMessage;
}
/**
* Method used to print the SOAP Response
*/
private static void printSOAPResponse(SOAPMessage soapResponse) throws Exception {
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
Source sourceContent = soapResponse.getSOAPPart().getContent();
System.out.print("\nResponse SOAP Message = ");
StreamResult result = new StreamResult(System.out);
transformer.transform(sourceContent, result);
}
/**
* #param args
*/
public static void main(String[] args) {
Test t = new Test();
t.submitOrder();
}
}
CORRECTION: the SOAP envelopes being created by Tomcat and WebSphere are not the same. Tomcat, using Java 1.6, creates the following:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<Orders>
while WebSphere, using IBM's version of 1.5, creates the following:
<soapenv:Envelope 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">
<soapenv:Header/>
<soapenv:Body>
<Orders>
How would I get WebSphere to create the same SOAP envelop as Tomcat?

Titanium SOAP Call ActionNotSupported using suds.js

I have http://192.168.15.45:8081/Taqeem.CRM.Appointments.Service.svc?wsdl service and method BookAppointment and I have also mentioned the parameters in the code and it is values.
var url = "http://192.168.15.45:8081/Taqeem.CRM.Appointments.Service.svc?wsdl";
var callparams = {
AppointmentNumber: 'APP-00000003-H042S5',
UserId: '4'
};
var suds = new SudsClient({
endpoint: url,
targetNamespace: 'http://tempuri.org'
});
try {
suds.invoke('BookAppointment', {}, function(xmlDoc) {
var ManifestXML = this.responseText;
console.log(ManifestXML);
var results = xmlDoc.documentElement.getElementsByTagName('ResultCode').text;
console.log('result'+ results);
if (results && results.length>0) {
var result = results.item(0);
label.text = '1 Euro buys you ' + results.item(0).text + ' U.S. Dollars.';
} else {
label.text = 'Oops, could not determine result of SOAP call.';
}
});
} catch(e) {
Ti.API.error('Error: ' + e);
}
I've used the suds.js and when I execute the below code. I get the error as ActionNotSupport
Complete response:
[INFO] : <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<s:Fault>
<faultcode xmlns:a="http://schemas.microsoft.com/ws/2005/05/addressing/none">
a:ActionNotSupported
</faultcode>
<faultstring xml:lang="en-US">
The message with Action 'http://tempuri.org/BookAppointment' cannot be processed at the receiver, due to a ContractFilter mismatch at the EndpointDispatcher. This may be because of either a contract mismatch (mismatched Actions between sender and receiver) or a binding/security mismatch between the sender and the receiver. Check that sender and receiver have the same contract and the same binding (including security requirements, e.g. Message, Transport, None).
</faultstring>
</s:Fault>
</s:Body>
</s:Envelope>
I feel like I'm passing the wrong TargetNameSpace but I have checked in http://192.168.15.45:8081/Taqeem.CRM.Appointments.Service.svc?wsdl and its good. I request to check the above link for list of methods.
I've used the SOAP UI and it is executing perfect. I get the perfect response.

Testing ASP.NET Web API Multipart Form Data File upload

I am trying to use N-UNIT to test my web API application but I am unable to find a proper way to test my file upload method. Which would be the best approach to test the method?
Web API Controller:
[AcceptVerbs("post")]
public async Task<HttpResponseMessage> Validate()
{
// Check if the request contains multipart/form-data.
if (!Request.Content.IsMimeMultipartContent())
{
return Request.CreateErrorResponse(HttpStatusCode.UnsupportedMediaType,"please submit a valid request");
}
var provider = new MultipartMemoryStreamProvider(); // this loads the file into memory for later on processing
try
{
await Request.Content.ReadAsMultipartAsync(provider);
var resp = new HttpResponseMessage(HttpStatusCode.OK);
foreach (var item in provider.Contents)
{
if (item.Headers.ContentDisposition.FileName != null)
{
Stream stream = item.ReadAsStreamAsync().Result;
// do some stuff and return response
resp.Content = new StringContent(result, Encoding.UTF8, "application/xml"); //text/plain "application/xml"
return resp;
}
}
return resp;
}
catch (System.Exception e)
{
return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, e);
}
}
Based on your above comment, following is an example:
HttpClient client = new HttpClient();
MultipartFormDataContent formDataContent = new MultipartFormDataContent();
formDataContent.Add(new StringContent("Hello World!"),name: "greeting");
StreamContent file1 = new StreamContent(File.OpenRead(#"C:\Images\Image1.jpeg"));
file1.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg");
file1.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data");
file1.Headers.ContentDisposition.FileName = "Image1.jpeg";
formDataContent.Add(file1);
StreamContent file2 = new StreamContent(File.OpenRead(#"C:\Images\Image2.jpeg"));
file2.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg");
file2.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data");
file2.Headers.ContentDisposition.FileName = "Image1.jpeg";
formDataContent.Add(file2);
HttpResponseMessage response = client.PostAsync("http://loclhost:9095/api/fileuploads", formDataContent).Result;
The request over the wire would like:
POST http://localhost:9095/api/fileuploads HTTP/1.1
Content-Type: multipart/form-data; boundary="34d56c28-919b-42ab-8462-076b400bd03f"
Host: localhost:9095
Content-Length: 486
Expect: 100-continue
Connection: Keep-Alive
--34d56c28-919b-42ab-8462-076b400bd03f
Content-Type: text/plain; charset=utf-8
Content-Disposition: form-data; name=greeting
Hello World!
--34d56c28-919b-42ab-8462-076b400bd03f
Content-Type: image/jpeg
Content-Disposition: form-data; filename=Image1.jpeg
----Your Image here-------
--34d56c28-919b-42ab-8462-076b400bd03f
Content-Type: image/jpeg
Content-Disposition: form-data; filename=Image2.jpeg
----Your Image here-------
--34d56c28-919b-42ab-8462-076b400bd03f--
After spending a bit of time looking into WebClient I was able to come up with this:
try
{
var imageFile = Path.Combine("dir", "fileName");
WebClient webClient = new WebClient();
byte[] rawResponse = webClient.UploadFile(string.Format("{0}/api/values/", "http://localhost:12345/"), imageFile);
Console.WriteLine("Sever Response: {0}", System.Text.Encoding.ASCII.GetString(rawResponse)); // for debugging purposes
Console.WriteLine("File Upload was successful");
}
catch (WebException wexc)
{
Console.WriteLine("Failed with an exception of " + wexc.Message);
// anything other than 200 will trigger the WebException
}