Sending SOAP message with C# Help Needed - c#

I would like to send a SOAP Message to a Web Service and read the response. My code is as follows: I will appreciate your help.
I hope my question is not repeated, I have looked around for a solution however I have not been successful.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.Services;
using System.Xml;
using System.Net;
using System.IO;
namespace TolunaPush
{
public partial class _Default : System.Web.UI.Page
{
private string sourceID = "50001255";
private string email = "adsvine#gmail.com";
private string firstName = "Muz";
private string lastName = "Khan";
private string countryID = "2000077";
private string countryLanguage = "2000240";
private string postalCode = "N19 3NU";
private string dob = "1977-03-08";
private string gender = "2000247";
protected void Page_Load(object sender, EventArgs e)
{
sendSoapMessage();
}
protected void sendSoapMessage()
{
XmlDocument doc = new XmlDocument();
doc.InnerXml = #"<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>
<SubmitPanelist xmlns=""http://www.greenfield.com/RegistrationGateway/Messages"">
<Registration xmlns=""http://www.greenfield.com/RegistrationGateway/Types"">
<Source>
<SourceID>" + sourceID + #"</SourceID>
</Source>
<Email>" + email + #"</Email>
<FirstName>" + firstName + #"</FirstName>
<LastName>" + lastName + #"</LastName>
<CountryUK>
<CountryID>" + countryID + #"</CountryID>
<Language>" + countryLanguage + #"</Language>
<Address>
<Postalcode>" + postalCode + #"</Postalcode>
</Address>
</CountryUK>
<DOB>" + dob + #"</DOB>
<Gender>" + gender + #"</Gender>
</Registration>
</SubmitPanelist>
</soap:Body>
</soap:Envelope>";
HttpWebRequest req = (HttpWebRequest)WebRequest.Create("http://coreg.surveycenter.com/RegistrationGateway/PanelistService.asmx");
//if (proxy != null) req.Proxy = new WebProxy(proxy, true);
// req.Headers.Add("GetClientInfo", "http://tempuri.org/GetClientInfo");
req.ContentType = "text/xml;charset=\"utf-8\"";
req.Accept = "text/xml";
req.Method = "POST";
Stream stm = req.GetRequestStream();
doc.Save(stm);
stm.Close();
WebResponse resp = req.GetResponse();
stm = resp.GetResponseStream();
StreamReader r = new StreamReader(stm);
Response.Write(r.ReadToEnd());
//Response.Write(stm.ToString());
//Response.Write(r.ToString());
Response.End();
}
}
}
Update
As suggested by Darin. I did as instructed however the following line of code
using (var client = new RegistrationBindingsClient("RegistrationBindings"))
gives the error
The type or namespace name 'RegistrationBindingsClient' could not be found (are you missing a using directive or an assembly reference?)
Any help will be greatly appreciated

The web service you are trying to consume offers a WSDL at the following address. So simply right click on the References in the solution explorer and use the Add Service Reference dialog in Visual Studio and point to the WSDL and it will generate strongly typed classes for you to easily consume the service, just like this:
protected void sendSoapMessage()
{
using (var client = new RegistrationBindingsClient("RegistrationBindings"))
{
var registration = new RegistrationType();
registration.Source = new SourceType();
registration.Source.SourceID = "50001255";
registration.Email = "adsvine#gmail.com";
registration.FirstName = "Muz";
registration.LastName = "Khan";
var countryUK = new CountryTypeUK();
countryUK.CountryID = 2000077;
countryUK.Language = 2000240;
countryUK.Address = new AddressTypeUK();
countryUK.Address.Postalcode = "N19 3NU";
registration.Item = countryUK;
registration.DOB = new DateTime(1977, 3, 8);
registration.Gender = 2000247;
client.SubmitPanelist(registration);
}
}
See how easy it is. You should not worry about any SOAP and XML plumbing.
And if you are interested in the actual underlying SOAP envelope that is being sent on the wire using this request:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<SubmitPanelist xmlns="http://www.greenfield.com/RegistrationGateway/Messages">
<Registration xmlns="http://www.greenfield.com/RegistrationGateway/Types">
<Source>
<SourceID>50001255</SourceID>
</Source>
<Email>adsvine#gmail.com</Email>
<FirstName>Muz</FirstName>
<LastName>Khan</LastName>
<CountryUK>
<CountryID>2000077</CountryID>
<Language>2000240</Language>
<Income>0</Income>
<Education>0</Education>
<Address>
<Postalcode>N19 3NU</Postalcode>
</Address>
</CountryUK>
<DOB>1977-03-08</DOB>
<Gender>2000247</Gender>
</Registration>
</SubmitPanelist>
</s:Body>
</s:Envelope>

Is there any error message or did you use an HTTP monitor?
Some maybe useful Links:
XmlDocument Save Method
How to: Send Data Using the WebRequest Class
Similar Question in stackoverflow maybe helpful

You can access the service in 2 methods:
By adding a web reference of the service. In visual studio you can right click on your project and select the option Add Web reference and then paste the URL of the service.
Generate client proxy from the wsdl using wsdl tool from Visual studio command prompt.The command would be as follows:
c:>wsdl "http://coreg.surveycenter.com/RegistrationGateway/PanelistService.asmx?wsdl
It would generate a .cs file and an output.config. Include the .cs file in your project and you can directly use it to access the service. Make sure that the config file entries are added to your projects config.
If you want to use HttpWebRequest then find the code below :
string soap =
#"<?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>
<Register xmlns=""http://tempuri.org/"">
<id>123</id>
<data1>string</data1>
</Register>
</soap:Body>
</soap:Envelope>";
HttpWebRequest req = (HttpWebRequest)WebRequest.Create("http://localhost/WebServices/CustomerWebService.asmx");
req.Headers.Add("SOAPAction", "\"http://tempuri.org/Register\"");
req.ContentType = "text/xml;charset=\"utf-8\"";
req.Accept = "text/xml";
req.Method = "POST";
using (Stream stm = req.GetRequestStream())
{
using (StreamWriter stmw = new StreamWriter(stm))
{
stmw.Write(soap);
}
}
WebResponse response = req.GetResponse();
Stream responseStream = response.GetResponseStream();
// TODO: Do whatever you need with the response
My Service looks like :
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class CustomerWebService : System.Web.Services.WebService
{
[WebMethod]
public string Register(long id, string data1)
{
return "ID.CUSTOMER";
}
}

Here's a general purpose class you can use to achieve what you need.
IMPORTANT DISCLAIMER: You should only use this when you want (or need) to manually issue a SOAP-based web service: in most common scenarios you should definitely use the Web Service WSDL together with the Add Service Reference Visual Studio feature, which is the proper way to do that.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Xml;
namespace Ryadel.Web.SOAP
{
/// <summary>
/// Helper class to send custom SOAP requests.
/// </summary>
public static class SOAPHelper
{
/// <summary>
/// Sends a custom sync SOAP request to given URL and receive a request
/// </summary>
/// <param name="url">The WebService endpoint URL</param>
/// <param name="action">The WebService action name</param>
/// <param name="parameters">A dictionary containing the parameters in a key-value fashion</param>
/// <param name="soapAction">The SOAPAction value, as specified in the Web Service's WSDL (or NULL to use the url parameter)</param>
/// <param name="useSOAP12">Set this to TRUE to use the SOAP v1.2 protocol, FALSE to use the SOAP v1.1 (default)</param>
/// <returns>A string containing the raw Web Service response</returns>
public static string SendSOAPRequest(string url, string action, Dictionary<string, string> parameters, string soapAction = null, bool useSOAP12 = false)
{
// Create the SOAP envelope
XmlDocument soapEnvelopeXml = new XmlDocument();
var xmlStr = (useSOAP12)
? #"<?xml version=""1.0"" encoding=""utf-8""?>
<soap12:Envelope xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance""
xmlns:xsd=""http://www.w3.org/2001/XMLSchema""
xmlns:soap12=""http://www.w3.org/2003/05/soap-envelope"">
<soap12:Body>
<{0} xmlns=""{1}"">{2}</{0}>
</soap12:Body>
</soap12:Envelope>"
: #"<?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>
<{0} xmlns=""{1}"">{2}</{0}>
</soap:Body>
</soap:Envelope>";
string parms = string.Join(string.Empty, parameters.Select(kv => String.Format("<{0}>{1}</{0}>", kv.Key, kv.Value)).ToArray());
var s = String.Format(xmlStr, action, new Uri(url).GetLeftPart(UriPartial.Authority) + "/", parms);
soapEnvelopeXml.LoadXml(s);
// Create the web request
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);
webRequest.Headers.Add("SOAPAction", soapAction ?? url);
webRequest.ContentType = (useSOAP12) ? "application/soap+xml;charset=\"utf-8\"" : "text/xml;charset=\"utf-8\"";
webRequest.Accept = (useSOAP12) ? "application/soap+xml" : "text/xml";
webRequest.Method = "POST";
// Insert SOAP envelope
using (Stream stream = webRequest.GetRequestStream())
{
soapEnvelopeXml.Save(stream);
}
// Send request and retrieve result
string result;
using (WebResponse response = webRequest.GetResponse())
{
using (StreamReader rd = new StreamReader(response.GetResponseStream()))
{
result = rd.ReadToEnd();
}
}
return result;
}
}
}
For additional info & details regarding this class you can also read this post on my blog.

Related

LoadXML Add Parameters

I'm doing LoadXML, but I need to add a field from the form but I couldn't,
XmlDocument soapEnvelopeDocument = new XmlDocument();
soapEnvelopeDocument.LoadXml(
#"<?xml version=""1.0"" encoding=""utf-8""?>
<soap:Envelope xmlns:soap=""http://schemas.xmlsoap.org/soap/envelope/"">
<soap:Body>
<Servis5001>
<Kodu>abcdefg</Kodu>
<Sifre>123456789</Sifre>
<HesKodu>TXBHesKodu.Text</HesKodu>
</Servis5001>
</soap:Body>
</soap:Envelope>");
return soapEnvelopeDocument;
I need to add the TXBHESKodu.Text from the form to the <HesKodu> field here.
I think I couldn't make the upper quotation marks added into the file.
Can you show me how to do it?
Here are two ways you could do that. The first being the simplest. Just use string formatting like this (note the $ sign before your # sign):
XmlDocument soapEnvelopeDocument = new XmlDocument();
soapEnvelopeDocument.LoadXml(
$#"<?xml version=""1.0"" encoding=""utf-8""?>
<soap:Envelope xmlns:soap=""http://schemas.xmlsoap.org/soap/envelope/"">
<soap:Body>
<Servis5001>
<Kodu>abcdefg</Kodu>
<Sifre>123456789</Sifre>
<HesKodu>{TXBHesKodu.Text}</HesKodu>
</Servis5001>
</soap:Body>
</soap:Envelope>");
The second method uses the XML Dom to add the text into the element. We find the element using the XPath syntax:
var xmlDocument = GetXmlDocument(#"<?xml version=""1.0"" encoding=""utf-8""?>
<soap:Envelope xmlns:soap=""http://schemas.xmlsoap.org/soap/envelope/"">
<soap:Body>
<Servis5001>
<Kodu>abcdefg</Kodu>
<Sifre>123456789</Sifre>
<HesKodu></HesKodu>
</Servis5001>
</soap:Body>
</soap:Envelope>");
XmlNode HesKodu = xmlDocument.SelectSingleNode("//Servis5001/HesKodu");
HesKodu.InnerText = TXBHesKodu.Text;
You would be better off letting Visual Studio handle all the SOAP stuff for you. Take a look at adding a reference to a SOAP Web Service Reference (right click on project and Add => Web Service Reference). You can simply enter the url with ?wsdl at the end and it will generate everything you need to consume the web service.
You can use the url in a webbrowser too. If you have access to the service you can simply enter the url in the addressbar and press Enter. It should give you a description of the service and how to consume it.
Method Usage Error When I Want to Add TXT HesKodu.Text
private static XmlDocument CreateSoapEnvelope()
{
XmlDocument soapEnvelopeDocument = new XmlDocument();
soapEnvelopeDocument.LoadXml(
$#"<?xml version=""1.0"" encoding=""utf-8""?>
<soap:Envelope xmlns:soap=""http://schemas.xmlsoap.org/soap/envelope/"">
<soap:Body>
<Servis5001>
<Kodu>abcdef</Kodu>
<Sifre>abcdef</Sifre>
<HesKodu>{TXBHesKodu.Text}</HesKodu>
</Servis5001>
</soap:Body>
</soap:Envelope>");
return soapEnvelopeDocument;
}
SOAP Whatever I Use My Blog Is All The Code Is As Below, Maybe If You Want To See It
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml;
namespace TOBBHesKoduSorgulama
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void BTNSorgula_Click(object sender, EventArgs e)
{
var _url = "https://kpsoda.tobb.org.tr/hesservis.php?wsdl";
var _action = "https://kpsoda.tobb.org.tr/hesservis.php?op=Servis5001";
var result = "";
XmlDocument soapEnvelopeXml = CreateSoapEnvelope();
HttpWebRequest webRequest = CreateWebRequest(_url, _action);
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();
}
result = soapResult;
Console.Write(soapResult);
}
}
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()
{
XmlDocument soapEnvelopeDocument = new XmlDocument();
soapEnvelopeDocument.LoadXml(
$#"<?xml version=""1.0"" encoding=""utf-8""?>
<soap:Envelope xmlns:soap=""http://schemas.xmlsoap.org/soap/envelope/"">
<soap:Body>
<Servis5001>
<Kodu>abcdef</Kodu>
<Sifre>abcdef</Sifre>
<HesKodu>{TXBHesKodu.Text}</HesKodu>
</Servis5001>
</soap:Body>
</soap:Envelope>");
return soapEnvelopeDocument;
}
private static void InsertSoapEnvelopeIntoWebRequest(XmlDocument soapEnvelopeXml, HttpWebRequest webRequest)
{
using (Stream stream = webRequest.GetRequestStream())
{
soapEnvelopeXml.Save(stream);
}
}
}
}
I also tried the Service References Process But I Didn't Know How To Request
string Kodu = "Kodu";
string Sifre = "Sifre";
string HesKodu = "HesKodu";
TOBBHesKoduSorgulamaServices.Servis5001Request S5001R = new TOBBHesKoduSorgulamaServices.Servis5001Request();
S5001R.Kodu = Kodu;
S5001R.Sifre = Sifre;
S5001R.HesKodu = HesKodu;
TOBBHesKoduSorgulamaServices.Servis5001Response S5001Response = ?
Which One Is Right For Me?
Waiting for your support, good work ...

SOAP Client using C#

I have Soap web service https://test-submit.health263.systems:8081/apacewebservices/AMF1_0?wsdl. This has a method called process. My question is how do I create soap client to send a request, that submits/Retrieves information from the server. The example XML for the request is shown below:
<?xml version="1.0" encoding="UTF-8"?>
<Member xmlns="urn:apace:member:format:1.0">
<Request>
<Transaction>
<VersionNumber>1.0</VersionNumber>
<Number>434252-342234-6765</Number>
<SystemIdentifier>SYSTEM999</SystemIdentifier>
<DestinationCode>APACE</DestinationCode>
<ClientCountryCode>ZA</ClientCountryCode>
<Timestamp TimeZone="Africa/Johannesburg">20160601123456</Timestamp>
<TestIndicator>Y</TestIndicator>
<User>ProviderX/Jane Doe</User>
</Transaction>
<MembershipLookup>
<Funder>AFunder</Funder>
<WithMembershipNumber>
<MembershipNumber>123456789</MembershipNumber>
</WithMembershipNumber>
</MembershipLookup>
</Request>
</Member>
The response message is structured as follows :
<?xml version="1.0" encoding="UTF-8"?>
<Member xmlns="urn:apace:member:format:1.0">
<Response>
<Transaction>
<VersionNumber>1.0</VersionNumber>
<Number>434252-342234-6765</Number>
<Status>S</Status>
<Timestamp TimeZone="Africa/Johannesburg">20160601123500</Timestamp>
</Transaction>
<Membership NumberOfBeneficiaryRecords="2">
<Funder>AFunder</Funder>
<MembershipNumber>123456789</MembershipNumber>
<Beneficiary SequenceNumber="1">
<DependentCode>00</DependentCode>
<Type>P</Type>
<Status>A</Status>
<BiometricEnrolmentStatus>Y</BiometricEnrolmentStatus>
</Beneficiary>
<Beneficiary SequenceNumber="2">
<DependentCode>01</DependentCode>
<Type>D</Type>
<Status>A</Status>
<BiometricEnrolmentStatus>Y</BiometricEnrolmentStatus>
</Beneficiary>
</Membership>
</Response>
</Member>
Please help I am really stuck, Haven't used SOAP services with C#, I have tried examples online but the structure does not follow my message structures are more complicated
The actual message structure is structured as follows:
<soap:Envelope
xmlns:soap="http://www.w3.org/2003/05/soap-envelope"
xmlns:apac="http://apace.systems/apacewebservices/"
xmlns:urn="urn:apace:member:format:1.1">
<soap:Header>
<apac:secureToken>Token66657752</apac:secureToken>
</soap:Header>
<soap:Body>
<apac:process>
<apac:request>
<Member
xmlns="urn:apace:member:format:1.1">
<Request>
<Transaction>
<VersionNumber>1.1</VersionNumber>
<Number>30074</Number>
<SystemIdentifier>LIFEHEALTH</SystemIdentifier>
<DestinationCode>HEALTH263</DestinationCode>
<ClientCountryCode>ZA</ClientCountryCode>
<Timestamp TimeZone="Africa/Johannesburg">20200705123456</Timestamp>
<TestIndicator>Y</TestIndicator>
<User>CIMSZW/Jane Doe</User>
</Transaction>
<MembershipLookup>
<IncludeDetail>Y</IncludeDetail>
<Funder>CIMSZWA</Funder>
<WithMembershipNumber>
<MembershipNumber>11117374</MembershipNumber>
<DependentCode>00</DependentCode>
</WithMembershipNumber>
</MembershipLookup>
</Request>
</Member>
</apac:request>
</apac:process>
</soap:Body>
</soap:Envelope>
Hw do I create the SOAP envelope and the Header part with the Security Key Token
You have two options
Add as service reference , it will genrate the
use Visual studio developer prompt and consume the service using a proxy class
svcutil.exe https://test-submit.health263.systems:8081/apacewebservices/AMF1_0?wsdl /t:code /n:*,SampleNamespace /o:C:\Service\sampleServiceProxy.cs /config:C:\Service\sampleService.config /ct:System.Collections.Generic.List`1
You can use a couple different system libraries to create an HttpWebRequest, create custom xml, and insert that xml into your request before you send it. (system.net, system.xml.linq, system.io)
I was able to hit your web service but got a 500 error. (Hopefully you see a log or that wasn't yours!)
Here's a simple class that can call a SOAP web service. It's almost the xml that you need but might need some tweaking. If you're having issues making custom xml this may be a possible solution.
using System;
using System.IO;
using System.Net;
using System.Text;
using System.Xml.Linq;
namespace ConsoleApp1
{
/// <summary>
/// Random class
/// </summary>
class Class1
{
/// <summary>
/// Function that calls a SOAP web service
/// </summary>
public void CallSOAP()
{
try
{
// Construct http post request
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(new Uri("https://test-submit.health263.systems:8081/apacewebservices/AMF1_0"));
request.Method = "POST";
request.ContentType = "application/xml";
request.Accept = "application/xml";
// Setting a namespace for your xml
// I'm not sure the timezone one is set up properly
XNamespace soap = "urn:apace:member:format:1.0";
XNamespace timezone = "TimeZone=\"Africa/Johannesburg\"";
// This constructs your xml using the LINQ library. I modeled after your demo, but needs tweaking as I get 500 error from server.
XElement requestXML =
new XElement(soap + "Member",
new XElement("Request",
new XElement("Transaction",
new XElement("VersionNumber", "1.0"),
new XElement("Number", "434252 - 342234 - 6765"),
new XElement("SystemIdentifier", "SYSTEM999"),
new XElement("DestinationCode", "APACE"),
new XElement("ClientCountryCode", "ZA"),
new XElement(timezone + "Timestamp", "20160601123456"),
new XElement("TestIndicator", "Y"),
new XElement("User", "ProviderX/Jane Doe")
),
new XElement("MembershipLookup",
new XElement("Funder", "AFunder"),
new XElement("WithMembershipNumber",
new XElement("MembershipNumber", 123456789)
)
)
)
);
// Convert the xml into a stream that we write to our request
byte[] bytes = Encoding.UTF8.GetBytes(requestXML.ToString());
request.ContentLength = bytes.Length;
using (Stream putStream = request.GetRequestStream())
{
putStream.Write(bytes, 0, bytes.Length);
}
// Execute the request and get an xml response "reader". You can read all xml at once or line by line
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
using (StreamReader reader = new StreamReader(response.GetResponseStream()))
{
var streamData = reader.ReadToEnd();
}
}
catch (Exception ex)
{
// Write exception to console & wait for key press
Console.WriteLine(ex.Message + ex.StackTrace);
Console.ReadKey();
}
}
}
}

.NET Soap request to Web service - Action not happening

I've searched and found lots on this topic, but I'm just not getting this to work. My request returns the HTML from asmx page that displays the web method (action), but does not perform the action, which basically returns a true/false.
I'm using the same SOAP 1.1 that my method provides. And, when I test the functionality by using the "Invoke" button provided it works just fine. But I really need to call this function behind-the-scenes so I can't use the HTTP Post like this button. Any ideas?
.cs code in App_Code directory of website:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Text;
using System.Web.Caching;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
[WebService(Namespace = "http://www.xxx.org/")]
public class VacationSickPayoutLogger : System.Web.Services.WebService
{
[WebMethod]
public string RunVacationSickPayoutWS()
{
return "True";
}
}
Code from asmx file:
<%# WebService Language="C#" CodeBehind="~/App_Code/VacationSickPayoutLogger.cs" Class="VacationSickPayoutLogger" %>
Code to call web method:
protected void Page_Load(object sender, EventArgs e)
{
string soap =
#"<?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>
<RunVacationSickPayoutWS xmlns=""http://www.xxx.org/"" />
</soap:Body>
</soap:Envelope>";
var _url = "http://localhost/HR/VacationSickPayoutLogger.asmx";
var _action = "\"http://www.xxx.org/RunVacationSickPayoutWS\"";
System.Xml.XmlDocument soapEnvelopeXml = CreateSoapEnvelope(soap);
HttpWebRequest webRequest = CreateWebRequest(_url, _action);
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();
}
Response.Write(soapResult);
}
}
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 System.Xml.XmlDocument CreateSoapEnvelope(string soap)
{
System.Xml.XmlDocument soapEnvelop = new System.Xml.XmlDocument();
soapEnvelop.LoadXml(soap);
return soapEnvelop;
}
private static void InsertSoapEnvelopeIntoWebRequest(System.Xml.XmlDocument soapEnvelopeXml, HttpWebRequest webRequest)
{
using (Stream stream = webRequest.GetRequestStream())
{
soapEnvelopeXml.Save(stream);
}
}

Soap Request in C#

I've got a soap request I've written in http & javascript but I cannot seem to convert it into C# correctly.
Original: (Works)
<button onclick="doStuff()" type="submit">Send</button>
<textarea name="REQUEST_DATA" cols=120 rows=17 >
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<createModifyRequest>
<username>josephs</username>
<lookupIds>
<lookupIds>4225</lookupIds><!--firepass-->
</lookupIds>
</createModifyRequest>
</soap:Body>
</soap:Envelope>
</textarea>
<script language="javascript">
function doStuff() {
var xmlhttp = new ActiveXObject("Msxml2.XMLHTTP.3.0");
xmlhttp.open("POST", "http://tpdev-itreq.transpower.co.nz:7777/usr/services/CreateModifyRequest", false);
xmlhttp.setRequestHeader("SOAPAction", "createModifyRequest");
var userpass = "josephs" + ":" + "pass";
xmlhttp.setRequestHeader("Authorization", "Basic " + (userpass));
xmlhttp.setRequestHeader("Content-Type", "text/xml");
xmlhttp.send(REQUEST_DATA.value);
}
Converted in C# (Does not work)
private void button1_Click(object sender, EventArgs e)
{
string soap =#"<?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>
<createModifyRequest>
<username>josephs</username>
<lookupIds>
<lookupIds>4225</lookupIds>
<!--firepass-->
</lookupIds>
</createModifyRequest>
</soap:Body>
</soap:Envelope>";
HttpWebRequest req = (HttpWebRequest)WebRequest.Create("http://tpdev-itreq.transpower.co.nz:7777/usr/services/CreateModifyRequest");
req.Headers.Add("SOAPAction", "\"createModifyRequest\"");
var userpass = "josephs" + ":" + "pass";
req.Headers.Add("Authorization", "Basic " + (userpass));
// req.Headers.Add("Content-Type", "text/xml");
req.ContentType = "text/xml;charset=\"utf-8\"";
req.Accept = "text/xml";
req.Method = "POST";
using (Stream stm = req.GetRequestStream())
{
using (StreamWriter stmw = new StreamWriter(stm))
{
stmw.Write(soap);
}
}
WebResponse response = req.GetResponse();
Stream responseStream = response.GetResponseStream();
// TODO: Do whatever you need with the response
}
At the moment when I run the C# code I get an internal 500 server error, so what have I done wrong?
I have tried to reproduce your problem. Currently i am not able to create your request but i have generated local request with your data.
One thing I came to know is if I remove double quotes(") around the utf-8 and it worked fine.
Just pass charset=utf-8 instead of charset=\"utf-8\""
I am not sure it will work for you or not.
Is there a reason you can't just use Visual Studio's built in support for SOAP web services?
You can add a service reference or a web reference (depending on whch framework version you are targeting).
Then you can just use the proxy class that VS creates for you.
There's no advantage to writing all of the HTTP code yourself. Actually, there's a big disadvantage, in that you are aren't getting proper data types from the WSDL of your SOAP service.

RESTful WCF receiving Base64 message. Need to convert message back to XML

I am having some trouble trying to write code within a RESTful WCF service. I have made a method available to a calling client application and I am receiving a message that is of the format Ax27834...... which is a Base64 Binary message. The issue is that following receiving this I need to be able to convert it back to the original xml version of that message that was sent from the client. How can I achieve this in the code snippet below. On line 6 below you will see where the code needs to go. I have searched for a solution but not managed to find anything suitable. I have to receive a message rather than a stream.
I should highlight that the service works fine in the respect of receiving the request. I am just struggling to get the message into a form that I can use.
The receiving code
public Message StoreMessage(Message request)
{
//Store the message
try
{
string message = [NEED SOLUTION HERE]
myClass.StoreNoticeInSchema(message, DateTime.Now);
}
catch (Exception e)
{
log4net.Config.XmlConfigurator.Configure();
ILog log = LogManager.GetLogger(typeof(Service1));
if (log.IsErrorEnabled)
{
log.Error(String.Format("{0}: Notice was not stored. {1} reported an exception. {2}", DateTime.Now, System.Reflection.MethodBase.GetCurrentMethod().DeclaringType, e.Message));
}
}
XElement responseElement = new XElement(XName.Get("elementName", "url"));
XDocument resultDocument = new XDocument(responseElement);
return Message.CreateMessage(OperationContext.Current.IncomingMessageVersion, "elementName", resultDocument.CreateReader());
}
The client code
public string CallPostMethod()
{
const string action = "StoreNotice/New";
TestNotice testNotice = new TestNotice();
const string url = "http://myaddress:myport/myService.svc/StoreNotice/New";
string contentType = String.Format("application/soap+xml; charset=utf-8; action=\"{0}\"", action);
string xmlString = CreateSoapMessage(url, action, testNotice.NoticeText);
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
ASCIIEncoding encoding = new ASCIIEncoding();
byte[] bytesToSend = encoding.GetBytes(xmlString);
request.Method = "POST";
request.ContentLength = bytesToSend.Length;
request.ContentType = contentType;
using (Stream requestStream = request.GetRequestStream())
{
requestStream.Write(bytesToSend, 0, bytesToSend.Length);
requestStream.Close();
}
string responseFromServer;
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
using (Stream dataStream = response.GetResponseStream())
{
using (StreamReader reader = new StreamReader(dataStream))
responseFromServer = reader.ReadToEnd();
dataStream.Close();
}
XDocument document = XDocument.Parse(responseFromServer);
string nameSpace = "http://www.w3.org/2003/05/soap-envelope";
XElement responseElement = document.Root.Element(XName.Get("Body", nameSpace))
.Element(XName.Get(#action + "Response", "http://www.wrcplc.co.uk/Schemas/ETON"));
return responseElement.ToString();
}
Code to create SOAP message
protected string CreateSoapMessage(string url, string action, string messageContent)
{
return String.Format(
#"<?xml version=""1.0"" encoding=""utf-8""?>
<soap12:Envelope xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance""
xmlns:xsd=""http://www.w3.org/2001/XMLSchema"" xmlns:soap12=""http://www.w3.org/2003/05/soap-envelope""><soap12:Body>{0}</soap12:Body>
</soap12:Envelope>
", messageContent, action, url);
}
NOTE: The TestNotice() object contains a large xml string which is the body of the message.
With a Message object you usually use GetReaderAtBodyContents() to get an XML representation of the body content, unless you know what type the body has then you can use GetBody<>. Try using those to get the string, and then decode it if you still need to. Which you can do as follows:
byte[] encodedMessageAsBytes = System.Convert.FromBase64String(requestString);
string message = System.Text.Encoding.Unicode.GetString(encodedMessageAsBytes);
From there you can reconstruct the xml from the string
Edit: to answer the last part from the comment, the content type should be: text/xml

Categories

Resources