How to make a SOAP/WSDL client in C#?
The simplest way is to use VS and add a web reference. This automatically creates the stub for you
Create SOAP webservice(wsdl) client in c#
Having Drew's method in mind,
- Right click on the project and select "add a service reference' and click "Advanced.." in add service reference dialog box. Then click "Add web reference" in add service reference dialog box. Input your webservice address in the address bar and click go. then rename your web reference name and click add reference.
(for ws security)
2.Go to the Reference.cs and change System.Web.Services.Protocols.SoapHttpClientProtocol
to Microsoft.Web.Services2.WebServicesClientProtocol
(You might have to add service2 by nuget)
- Before calling your webservice, add this.
UsernameToken token = new UsernameToken("", "", PasswordOption.SendPlainText);
yourProxy.RequestSoapContext.Security.Tokens.Add(token);
How to create SOAP/XML client from WSDL in console cron job app C# vs2012
You are not alone in being confused. You have to realize classic SOAP (asmx/wsdl) is considered an "outdated" technology (by Microsoft), so these days it hidden away in the toolset in favor of newer technologies. The most basic approach is to add it as a Reference from the solution explorer within Visual Studio itself. Here is a step-by-step:
- Create a console application
- In the solution explorer, right-click the References node and choose Add Service Reference
- Ignore most of the dialog that comes up, and go straight for Advanced:
- From the bottom of the Service Reference Setttings, choose Add Web Reference...
- Now fill in the location of your ASMX, hit the little arrow, wait a bit for the tooling to discover the service, then hit Add Reference
- This will add a Web Reference to your project that you can then use to access the methods of the webservice.
[Edit] (to answer your question)
If you have a .WSDL file on disk, you simply enter the file location on disk in the URL box of the Add Web Reference dialog:
In that case, the generated service has a default namespace of WebReference (unless you change it, of course), and you'll most likely want to explicitly set the URL:
var service = new WebReference.GlobalWeather {Url = "http://www.webservicex.net/globalweather.asmx"};
var weather = service.GetWeather("Amsterdam", "Netherlands");
Console.WriteLine(weather);
SOAP Client using C#
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();
}
}
}
}
Client to send SOAP request and receive response
I normally use another way to do the same
using System.Xml;
using System.Net;
using System.IO;
public static void CallWebService()
{
var _url = "http://xxxxxxxxx/Service1.asmx";
var _action = "http://xxxxxxxx/Service1.asmx?op=HelloWorld";
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();
}
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(
@"<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>
<HelloWorld xmlns=""http://tempuri.org/""
SOAP-ENV:encodingStyle=""http://schemas.xmlsoap.org/soap/encoding/"">
<int1 xsi:type=""xsd:integer"">12</int1>
<int2 xsi:type=""xsd:integer"">32</int2>
</HelloWorld>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>");
return soapEnvelopeDocument;
}
private static void InsertSoapEnvelopeIntoWebRequest(XmlDocument soapEnvelopeXml, HttpWebRequest webRequest)
{
using (Stream stream = webRequest.GetRequestStream())
{
soapEnvelopeXml.Save(stream);
}
}
SOAP client in .NET referencing existing WSDL
I found the solution to this problem by myself. After lots of trial and error modifications I came to the conclusion that the word "parameters" is not very welcome into .NET environment. So I changed it with "params" and now it is correctly imported by wsdl.exe
So part of my previous WSDL was something like:
<wsdl:message name="isServiceOnline">
<wsdl:part name="parameters" element="MyElement"></wsdl:part>
</wsdl:message>
The new version of it is:
<wsdl:message name="isServiceOnline">
<wsdl:part name="params" element="MyElement"></wsdl:part>
</wsdl:message>
SOAP service client generated with WSDL configure signing body only
I have finally managed to solve this myself. I had binding security configured in my app.config but this appears to default to symmetric security, hence the HMAC-SHA1 which uses AES, a symmetric algorithm. Instead of configuring in app.config, I built my own binding using AsymmetricSecurity (shown below). This meant that signatures used RSA, an asymmetric algorithm, instead of AES, and upon doing this the remote server finally accepted the request.
AsymmetricSecurityBindingElement asbe = new AsymmetricSecurityBindingElement
{
MessageSecurityVersion = MessageSecurityVersion.WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10, // Or WSSecurity10WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10 ?
InitiatorTokenParameters = new X509SecurityTokenParameters { InclusionMode = SecurityTokenInclusionMode.AlwaysToRecipient },
RecipientTokenParameters = new X509SecurityTokenParameters(),
SecurityHeaderLayout = SecurityHeaderLayout.Strict,
IncludeTimestamp = true,
DefaultAlgorithmSuite = SecurityAlgorithmSuite.Basic128Rsa15,
AllowSerializedSigningTokenOnReply = true
};
asbe.SetKeyDerivation(false); // What is it for?
asbe.EndpointSupportingTokenParameters.Signed.Add(new X509SecurityTokenParameters { InclusionMode = SecurityTokenInclusionMode.AlwaysToRecipient });
CustomBinding binding = new CustomBinding();
binding.Elements.Add(asbe);
binding.Elements.Add(new TextMessageEncodingBindingElement(MessageVersion.Soap11, Encoding.UTF8));
binding.Elements.Add(new HttpsTransportBindingElement
{
MaxReceivedMessageSize = 1024 * 1024
});
Client.Endpoint.Binding = binding;
Related Topics
Adding an Incremental Number to Duplicate String
Entity Framework Migrations Renaming Tables and Columns
How to Cast a List into a Type Which Inherits from List<T>
How to Download a File from a Url in C#
How to Get the Display Name Attribute of an Enum Member Via MVC Razor Code
Use Linq to Collaps Multiply Collections into One Collection
How to Set Shadow Effect on Imageview
How to Set the Query Timeout from SQL Connection String
Convert Dictionary Values into Array
Httpcontext.Current.Request.Files Is Always Empty
How to Fix Json.Net (Newtonsoft.Json) Runtime File Load Exception
Restsharp Serializing Json Objects to Post Parameters
Localhost Port Is Changing in Visual Studio 2017
How to Split Json String in C# and Store in Separate Variables
How to Get Cookies Info Inside of a Cookiecontainer (All of Them, Not for a Specific Domain)
Browser Back Button Navigates to Login Page When User Is Still Logged In