How to Programmatically Connect a Client to a Wcf Service

How to programmatically connect a client to a WCF service?

You'll have to use the ChannelFactory class.

Here's an example:

var myBinding = new BasicHttpBinding();
var myEndpoint = new EndpointAddress("http://localhost/myservice");
using (var myChannelFactory = new ChannelFactory<IMyService>(myBinding, myEndpoint))
{
IMyService client = null;

try
{
client = myChannelFactory.CreateChannel();
client.MyServiceOperation();
((ICommunicationObject)client).Close();
myChannelFactory.Close();
}
catch
{
(client as ICommunicationObject)?.Abort();
}
}

Related resources:

  • How to: Use the ChannelFactory

Programmatically have Client application list a WCF service's Endpoints created during runtime using a URL (like WCF Test Client does)

Provided that we have the service metadata URI, we could use MetadataExchangeClientMode and MetadataResolver class which is provided in the System.ServiceModel.Description namespace to retrieve and process the metadata.

https://learn.microsoft.com/en-us/dotnet/framework/wcf/feature-details/how-to-use-metadataresolver-to-obtain-binding-metadata-dynamically

https://learn.microsoft.com/en-us/dotnet/framework/wcf/feature-details/how-to-use-metadataexchangeclient-to-retrieve-metadata

I have made a simple example, wish it is useful to you.

    class Program
{
static void Main(string[] args)
{
Uri uri = new Uri("http://10.157.13.69:3336/mex");
MetadataExchangeClient client = new MetadataExchangeClient(uri, MetadataExchangeClientMode.MetadataExchange);
MetadataSet metadata = client.GetMetadata();
WsdlImporter importer = new WsdlImporter(metadata);
ServiceEndpointCollection endpoints = importer.ImportAllEndpoints();

//ServiceEndpointCollection endpoints = MetadataResolver.Resolve(typeof(IService), uri, MetadataExchangeClientMode.MetadataExchange);
foreach (var item in endpoints)
{
Console.WriteLine(item.Address.Uri);
}
}
}
[ServiceContract]
public interface IService
{
[OperationContract]
string SayHello();
}

Result
Sample Image

Programmatically create WCF Client


Error   1   'Proxy<...>': cannot declare instance members in a static class

Look at the class that this method is inside and make sure it's not static.

Error   3   The type or namespace name 'T' could not be found (are you missing a using directive or an assembly reference?)

When you see a definition for a generic class like ChannelFactory<T> or List<T>, T is just a placeholder for the actual type, like List<string> or List<DateTime>. From looking at the code above I'm guessing it's ChannelFactory<IReportData>.


Here's a really simple client. I used the sample service that gets created whenever you make a new WCF application project.

public class MyServiceClient : ClientBase<IService>, IService
{
public string GetData(int value)
{
return base.Channel.GetData(value);
}

public CompositeType GetDataUsingDataContract(CompositeType composite)
{
return base.Channel.GetDataUsingDataContract(composite);
}
}

From the documentation for ChannelFactory:

The generic ChannelFactory class is used in advanced
scenarios that require the creation of a channel factory that can be
used to create more than one channel.

In other words, if you're just trying to create a client then you probably don't need to use ChannelFactory.


In practice, I use Castle Windsor WCF Integration Facility to create my WCF clients. That's only applicable if you're interested in using dependency injection and working with Castle Windsor. I highly recommend learning to work with it just because dependency injection is a useful practice. But then in addition to that you get the convenience of using it to create and dispose your clients.

The result is that your classes never "know" about the WCF service. They just know that they're using IReportData. They have no idea that the implementation of that interface is a WCF client. Behind the scenes Windsor is creating and disposing the client, and in most cases the only configuration is a one-line <endpoint> element in your app.config.

Here's the entry page for their documentation.

Programmatically adding an endpoint

To create endpoints and bindings programmatically, you could do this on the service:

ServiceHost _host = new ServiceHost(typeof(TestService), null);

var _basicHttpBinding = new System.ServiceModel.basicHttpBinding();
//Modify your bindings settings if you wish, for example timeout values
_basicHttpBinding.OpenTimeout = new TimeSpan(4, 0, 0);
_basicHttpBinding.CloseTimeout = new TimeSpan(4, 0, 0);
_host.AddServiceEndpoint(_basicHttpBinding, "http://192.168.1.51/TestService.svc");
_host.Open();

You could also define multiple endpoints in your service config, and choose which one to connect to dynamically at run time.

On the client program you would then do this:

basicHttpBinding _binding = new basicHttpBinding();
EndpointAddress _endpoint = new EndpointAddress(new Uri("http://192.168.1.51/TestService.svc"));

TestServiceClient _client = new TestServiceClient(_binding, _endpoint);
_client.BlahBlah();

WCF - how programmatically set bindingconfiguration?

done work code so:

InstanceContext context = new InstanceContext(new ChatClient(numberclient));
NetPeerTcpBinding binding = new NetPeerTcpBinding();

EndpointAddress endpoint = new EndpointAddress("net.p2p://ChangingName123/FileServer");
binding.Resolver.Custom.Address = new EndpointAddress("net.tcp://191.14.3.11/FileServer");
binding.Security.Mode = SecurityMode.None;
NetTcpBinding ntcp = new NetTcpBinding();
ntcp.Security.Mode = SecurityMode.None;
binding.Resolver.Custom.Binding = ntcp;
factory = new DuplexChannelFactory<IChatChannel>(context, binding, endpoint);
channel = factory.CreateChannel();

WCF programmatic incorporation of service endpoint address

You can programmatically configure your endpoint. See:

http://msdn.microsoft.com/en-us/library/ff647110.aspx

This stack post covers detecting if a port is free:

In C#, how to check if a TCP port is available?

Here's another link with some programmatic endpoint configuration:

http://en.csharp-online.net/WCF_Essentials%E2%80%94Programmatic_Endpoint_Configuration

So, something like:

string svcUri = String.Format("net.tcp://localhost:{0}", port);
ServiceHost host = new ServiceHost(typeof(MyService));
Binding tcpBinding = new NetTcpBinding( );
host.AddServiceEndpoint(typeof(IMyOtherContract),tcpBinding,
svcUri);
host.Open( );


Related Topics



Leave a reply



Submit