C# SOAP client causing exception - c#

Fairly new to SOAP however not new to C# or PHP. I have created a basic SOAP service at http://basic.tip2tail.co.uk/?wsdl. This should expose a method submitSoap which takes a string parameter and returns an integer.
I have tested this SOAP service by connecting a simple client I have written in another language and confirmed it works as expected.
However, I cannot get my head round this in C#. I have added a Service Reference pointing at my WSDL. It shows as 2 services. The method shows as exposed under BasicSOAP_PortType.
I have then added using SOAPTest.BasicSOAP; to my C# program. However I cannot work out how to then code a call to this method. I thoughts it would be similar to (in a button click event):
BasicSOAP_PortType oSoap = new BasicSOAP_PortType();
int iReturn = oSoap.submitSoap("this is the string sent");
However this does not work and generates the following exception:
An unhandled exception of type 'System.InvalidOperationException' occurred in System.ServiceModel.dll
Additional information: Could not find default endpoint element that references contract 'BasicSOAP.BasicSOAP_PortType' in the ServiceModel client configuration section. This might be because no configuration file was found for your application, or because no endpoint element matching this contract could be found in the client element.
Any help appreciated!
Mark

I got it to work. After adding the service ref, my code looks like this:
using (var client = new basicsoap_ref.BasicSOAP_PortTypeClient())
{
try
{
int result = 0;
string resultString = client.submitSoap("<root><test>Will</test></root>");
int.TryParse(resultString, out result);
Console.WriteLine(result);
}
catch (Exception ex)
{
Console.Write(ex.Message);
}
Console.Write("Done");
}
And the service model portion of my config file looks like this:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicSOAP_Binding" />
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://basic.tip2tail.co.uk/"
binding="basicHttpBinding" bindingConfiguration="BasicSOAP_Binding"
contract="basicsoap_ref.BasicSOAP_PortType" name="MyServicesSoap" />
</client>
</system.serviceModel>

Related

Pass a valid endpoint name to the service client constructor

I try to use web service for weather
http://www.webservicex.com/globalweather.asmx?WSDL
I make console application and try to use this service. First of all I add reference and name the reference WeatherService and write below code
Console.WriteLine("Now we get weather, please wait .......");
WeatherService.GlobalWeatherSoapClient w = new WeatherService.GlobalWeatherSoapClient();
Console.WriteLine(w.GetWeather("Lahore","Pakistan"));
But it gives me a exception
Additional information: An endpoint configuration section for contract 'WeatherService.GlobalWeatherSoap' could not be loaded because more than one endpoint configuration for that contract was found. Please indicate the preferred endpoint configuration section by name.
I am learning web services and don't know why this happens. Any one help me on this is great favor. Advance thanks.
Open your app.config, find needed then pass it's name to GlobalWeatherSoapClient(here):
in your app.config should be setting like this:
<endpoint address="http://www.webservicex.com/globalweather.asmx"
binding="basicHttpBinding" bindingConfiguration="GlobalWeatherSoap"
contract="WeatherService.GlobalWeatherSoap" name="GlobalWeatherSoap" />
get name and pass it to client:
WeatherService.GlobalWeatherSoapClient w = new WeatherService.GlobalWeatherSoapClient("GlobalWeatherSoap");

Could not find endpoint element with name 'xxxxx' and contract 'yyy' in the ServiceModel client configuration section

I generated a proxy via this command -
svcutil.exe /language:cs /out:generatedProxy.cs /config:app.config https://service100.emedny.org:9047/MHService?wsdl
and then copied the elements from the resulting app.config into the app.config file of an existing project.
When I try to access the client in that config file via-
MHSClient serviceProxy = new MHSClient("MHSPort");
it should reference the second client below:
<client>
<endpoint address="https://webservices.hmsa.com/EDI27X/cstc/Hipaa27XService.svc"
binding="customBinding"
bindingConfiguration="wsHttpEndpoint"
contract="HIPAA27XServiceContract"
name="wsHttpEndpoint" />
<endpoint address="https://12.23.28.113:9047/MHService"
binding="customBinding"
bindingConfiguration="MHService_MHSPort"
contract="MHS"
name="MHSPort" />
</client>
but instead I get the error;
Could not find endpoint element with name 'MHSPort' and contract 'MHS' in the ServiceModel client configuration section. This might be because no configuration file was found for your application, or because no endpoint element matching this name could be found in the client element.'
If I go to definition of MHSClient, it takes me to the proxy.cs file and this line;
public partial class MHSClient : System.ServiceModel.ClientBase, MHS
solved with the following-
endptAddress = new EndpointAddress(new Uri("uri"/xxxx"), EndpointIdentity.CreateDnsIdentity("xxxxxx"), addressHeaders);
MHSClient serviceProxy = new MHSClient(b, endptAddress);
solved with the following-
endptAddress = new EndpointAddress(new Uri("uri"/xxxx"), EndpointIdentity.CreateDnsIdentity("xxxxxx"), addressHeaders);
MHSClient serviceProxy = new MHSClient(b, endptAddress);
#Guanxi gave me the clue when asking about endpoint address from the config file. Once I created the endpoint address then I could instantiate/create the service using the correct overload;
var b = new CustomBinding() as the first argument and for the second argument,
the correct endpoint address.
complicated - WS-Security - IBM Websphere server interop <-> wcf client within the context of various .NET and Visual Studio implementations of web services... oh my
You probably need to set the ConfigurationName property of the ServiceContractAttribute above the service contract interface, ConfigurationName should match your contract name.
'VB.NET:
Imports System.ServiceModel
<ServiceContract([Namespace]:="http://yournamespace", ConfigurationName:="MHS")> _
Public Interface MHS
//C#:
using System.ServiceModel;
[ServiceContract(Namespace="http://yournamespace", ConfigurationName="MHS")]
public interface MHS
Look at the auto generated code here:
MSDN: How to: Create a Windows Communication Foundation Client
Also worth looking at:
MSDN: ServiceContractAttribute Class

Could not find endpoint element with name and contract

I have added reference to a WCF service that has two end points. On adding the service the following get added to the Config file:
<client>
<endpoint name="ABCServiceV1" address="http://staging.ABCwebservices.com/ABC/Service.svc"
binding="basicHttpBinding" bindingConfiguration="ABCServiceV1"
contract="ABCService.IService" />
<endpoint name="ABCServiceV2" address="http://staging.ABCwebservices.com/ABC/Service.svc/20"
binding="basicHttpBinding" bindingConfiguration="ABCServiceV2"
contract="ABCService.IService1" />
</client>
The code to create the client is as as below:
ABCService.ServiceClient ABCClient = new ServiceClient("ABCServiceV2");
However, I am getting an runtime error - "Could not find endpoint element with name 'ABCServiceV2' and contract 'ABCService.IService' in the ServiceModel client configuration section. This might be because no configuration file was found for your application, or because no endpoint element matching this name could be found in the client element."
if i used ABCService.ServiceClient ABCClient = new ServiceClient("ABCServiceV1"); then everything works fine. But when using ABCServiceV2 it is trying to look for Contract - ABCService.IService - when it should be looking for - ABCService.IService1.
How do i make it look for the correct contract?
If you added a second reference to a different service (ABCServiceV2) then I believe this will have generated a second service class for ABCServiceV2. The two classes will implement separate contracts (ABCService.IService and ABCService.IService1) so you won't be able to interchange the endpoints.
I believe you should be able to initialise your two service endpoints like so:
ABCService.ServiceClient ABCClient = new ServiceClient("ABCServiceV1");
ABCService.Service1Client ABCClient1 = new Service1Client("ABCServiceV2");
Even though this post is old and answered, the answer didn't help in my case.
My problem was I generated the service client with the svcutil.exe tool, but didn't specify any namespace at all; and so the contract namespace name was generated as the target namespace of the schema document by default, yes total mess.
On the other hand I was trying to use the config file generated when a service reference is added to the project. The contract namespace in this file is ServiceReference1 (by default) or any other name you want, perfect storm! But all I had to do was to remove the namespace part from the FQN from the <endpoint>'s contract attribute, and the contract became visible to the CLR.
Hope this help others

How to determine the URL of a WCF Data Service's client reference?

To access OData on Windows Phone you do this:
// Declare the data service objects and URIs.
NorthwindEntities context;
Uri northwindUri =
new Uri("http://services.odata.org/Northwind/Northwind.svc/");
DataServiceCollection<Customer> customers;
// Initialize the context and the binding collection
context = new NorthwindEntities(northwindUri);
customers = new DataServiceCollection<Customer>(context);
// Define a LINQ query that returns all customers.
var query = from cust in context.Customers
select cust;
// Register for the LoadCompleted event.
customers.LoadCompleted
+= new EventHandler<LoadCompletedEventArgs>(customers_LoadCompleted);
// Load the customers feed by executing the LINQ query.
customers.LoadAsync(query);
But I already know the URL from the service reference.
Can't I just pass that to the URI argument?
Is there an easy way to access it's configured URL?
Is this a good idea?
If you have a service client defined you can get the URI used by doing:
client.Endpoint.Address.Uri
In the app.config the service reference is defined:
<client>
<endpoint address="http://localhost:36294/Services/Service1.svc"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IService1"
contract="ServiceReference1.IService1" name="BasicHttpBinding_IService1" />
</client>
If you have this in your application already (web.config for web app). Then you dont need to define the endpoint at all as it already exists and will be grabbed upon instantiation.
This is assuming that the service is a WCF service and a reference is added via 'Add Service Reference...'

WCF named pipe minimal example

I'm looking for minimal example of WCF Named Pipes (I expect two minimal applications, server and client, which can communicate via a named pipe.)
Microsoft has the briliant article Getting Started Tutorial that describes WCF via HTTP, and I'm looking for something similar about WCF and named pipes.
I've found several posts in the Internet, but they are a little bit "advanced". I need something minimal, only mandatory functionality, so I can add my code and get the application working.
How do I replace that to use a named pipe?
<endpoint address="http://localhost:8000/ServiceModelSamples/Service/CalculatorService"
binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_ICalculator"
contract="ICalculator" name="WSHttpBinding_ICalculator">
<identity>
<userPrincipalName value="OlegPc\Oleg" />
</identity>
</endpoint>
How do I replace that to use a named pipe?
// Step 1 of the address configuration procedure: Create a URI to serve as the base address.
Uri baseAddress = new Uri("http://localhost:8000/ServiceModelSamples/Service");
// Step 2 of the hosting procedure: Create ServiceHost
ServiceHost selfHost = new ServiceHost(typeof(CalculatorService), baseAddress);
try
{
// Step 3 of the hosting procedure: Add a service endpoint.
selfHost.AddServiceEndpoint(
typeof(ICalculator),
new WSHttpBinding(),
"CalculatorService");
// Step 4 of the hosting procedure: Enable metadata exchange.
ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = true;
selfHost.Description.Behaviors.Add(smb);
// Step 5 of the hosting procedure: Start (and then stop) the service.
selfHost.Open();
Console.WriteLine("The service is ready.");
Console.WriteLine("Press <ENTER> to terminate service.");
Console.WriteLine();
Console.ReadLine();
// Close the ServiceHostBase to shutdown the service.
selfHost.Close();
}
catch (CommunicationException ce)
{
Console.WriteLine("An exception occurred: {0}", ce.Message);
selfHost.Abort();
}
How do I generate a client to use a named pipe?
I just found this excellent little tutorial. broken link (Cached version)
I also followed Microsoft's tutorial which is nice, but I only needed pipes as well.
As you can see, you don't need configuration files and all that messy stuff.
By the way, he uses both HTTP and pipes. Just remove all code lines related to HTTP, and you'll get a pure pipe example.
Try this.
Here is the service part.
[ServiceContract]
public interface IService
{
[OperationContract]
void HelloWorld();
}
public class Service : IService
{
public void HelloWorld()
{
//Hello World
}
}
Here is the Proxy
public class ServiceProxy : ClientBase<IService>
{
public ServiceProxy()
: base(new ServiceEndpoint(ContractDescription.GetContract(typeof(IService)),
new NetNamedPipeBinding(), new EndpointAddress("net.pipe://localhost/MyAppNameThatNobodyElseWillUse/helloservice")))
{
}
public void InvokeHelloWorld()
{
Channel.HelloWorld();
}
}
And here is the service hosting part.
var serviceHost = new ServiceHost
(typeof(Service), new Uri[] { new Uri("net.pipe://localhost/MyAppNameThatNobodyElseWillUse") });
serviceHost.AddServiceEndpoint(typeof(IService), new NetNamedPipeBinding(), "helloservice");
serviceHost.Open();
Console.WriteLine("Service started. Available in following endpoints");
foreach (var serviceEndpoint in serviceHost.Description.Endpoints)
{
Console.WriteLine(serviceEndpoint.ListenUri.AbsoluteUri);
}
Check out my highly simplified Echo example:
It is designed to use basic HTTP communication, but it can easily be modified to use named pipes by editing the app.config files for the client and server. Make the following changes:
Edit the server's app.config file, removing or commenting out the http baseAddress entry and adding a new baseAddress entry for the named pipe (called net.pipe). Also, if you don't intend on using HTTP for a communication protocol, make sure the serviceMetadata and serviceDebug is either commented out or deleted:
<configuration>
<system.serviceModel>
<services>
<service name="com.aschneider.examples.wcf.services.EchoService">
<host>
<baseAddresses>
<add baseAddress="net.pipe://localhost/EchoService"/>
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors></serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
Edit the client's app.config file so that the basicHttpBinding is either commented out or deleted and a netNamedPipeBinding entry is added. You will also need to change the endpoint entry to use the pipe:
<configuration>
<system.serviceModel>
<bindings>
<netNamedPipeBinding>
<binding name="NetNamedPipeBinding_IEchoService"/>
</netNamedPipeBinding>
</bindings>
<client>
<endpoint address = "net.pipe://localhost/EchoService"
binding = "netNamedPipeBinding"
bindingConfiguration = "NetNamedPipeBinding_IEchoService"
contract = "EchoServiceReference.IEchoService"
name = "NetNamedPipeBinding_IEchoService"/>
</client>
</system.serviceModel>
</configuration>
The above example will only run with named pipes, but nothing is stopping you from using multiple protocols to run your service. AFAIK, you should be able to have a server run a service using both named pipes and HTTP (as well as other protocols).
Also, the binding in the client's app.config file is highly simplified. There are many different parameters you can adjust, aside from just specifying the baseAddress...
I created this simple example from different search results on the internet.
public static ServiceHost CreateServiceHost(Type serviceInterface, Type implementation)
{
//Create base address
string baseAddress = "net.pipe://localhost/MyService";
ServiceHost serviceHost = new ServiceHost(implementation, new Uri(baseAddress));
//Net named pipe
NetNamedPipeBinding binding = new NetNamedPipeBinding { MaxReceivedMessageSize = 2147483647 };
serviceHost.AddServiceEndpoint(serviceInterface, binding, baseAddress);
//MEX - Meta data exchange
ServiceMetadataBehavior behavior = new ServiceMetadataBehavior();
serviceHost.Description.Behaviors.Add(behavior);
serviceHost.AddServiceEndpoint(typeof(IMetadataExchange), MetadataExchangeBindings.CreateMexNamedPipeBinding(), baseAddress + "/mex/");
return serviceHost;
}
Using the above URI I can add a reference in my client to the web service.

Categories

Resources