I've been following Miguel Castro's excellent article on WCF here and it's all working nicely, except that I have the following code
public AdminClient()
{
ChannelFactory<IProductAdmin> factory = new ChannelFactory<IProductAdmin>();
productAdminChannel = factory.CreateChannel();
}
In my app.config file, I have the following configuration:
<system.serviceModel>
<client>
<endpoint address="net.tcp://localhost:8002/ProductBrowser"
binding="netTcpBinding"
contract="Contracts.IProductAdmin" />
</client>
</system.serviceModel>
But, when I run the constructor for AdminClient I get an exception saying that the endpoint isn't defined. However, if I change my configuration to give the endpoint a name, and then create the factory as follows, it works.
public AdminClient()
{
var fac = new ChannelFactory<IProductAdmin>("admin");
productAdminChannel = fac.CreateChannel();
}
<system.serviceModel>
<client>
<endpoint name="admin"
address="net.tcp://localhost:8002/ProductBrowser"
binding="netTcpBinding"
contract="Contracts.IProductAdmin" />
</client>
</system.serviceModel>
I'd love an explanation for this. The documentation in MSDN isn't much help...
Use "*" to use the first qualifying endpoint.
public AdminClient()
{
ChannelFactory<IProductAdmin> factory
= new ChannelFactory<IProductAdmin>("*");
productAdminChannel = factory.CreateChannel();
}
MSDN Example
You need to specify the endpoint name, because you can have many endpoints for the same type of contract. (For instance a service being deployed on one tcp and one http ws endpoint). Microsoft could have of course built something in WCF to check if there is only one client specified for the contract interface, but that wouldn't have been very consistent. (that it would work if there is only one endpoint specified for the contract). When you would add another endpoint for the same contract later, the code would break in that case.
You can get away without specifying endpoint name on service side. For client side, you need to specify the name, because you may be connecting to multiple services that have the same contract. How would WCF know then which one you want?
This has been bugging me for a few days, so I went through the examples shown in the article you linked above. Everything works correctly except for the second client proxy example that you're having a problem with. As you noted and the other answerers creating a proxy in that way requires an endpoint name, coupling it with the client (which is where the endpoint is defined). I'm still not sure why it behaves the way it does, but I found no way to use that example without explicitly coupling the proxy to the endpoint.
On the other hand, the first example showing how to create the proxy requires no explicit coupling of endpoint address or binding:
using System;
using System.ServiceModel;
namespace CoDeMagazine.ServiceArticle
{
public class ProductClient
: ClientBase<IProductBrowser>,
IProductBrowser
{
#region IProductBrowser Members
public ProductData GetProduct(
Guid productID)
{
return Channel.GetProduct(productID);
}
public ProductData[] GetAllProducts()
{
return Channel.GetAllProducts();
}
public ProductData[] FindProducts(
string productNameWildcard)
{
return Channel.FindProducts(
productNameWildcard);
}
#endregion
}
}
That seems to work just fine. So, maybe the second proxy example is just a poor way to do things, or maybe we're missing something obvious...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With