WCF proxy: Do I need to create a new and different proxy for each binding? - wcf

Let's say that I have created a WCF proxy from a WCF service (which is configured with wsHttpBinding) using Add Service (in Visual Studio 2008).
Later I want to use basicHttpBinding so I'll go and change the WCF service to use basicHttpBinding. But what about the WCF proxy? Can I just change this via Web.config or do I need to create the WCF proxy again from the WCF service via Add Service?
Thanks

It depends :-)
If you already have all the bindings in place when you do the Add Service Reference the first time around, then your client side proxy configuration will include all the bindings, and you can basically switch from using one to the other without any reconfiguration or anything. Each client endpoint (which has one specific binding) should have a name, so you can pick and choose:
MyServiceClient client = new MyServiceClient("endpointname");
However, if you add the second binding to your service after you've added the service reference to your client side code, then yes - you need to upgrade your service reference. To do so, open the Service References node in your solution explorer in the client side project, right click on that service reference you're interested in, and choose Update Service Reference from the context menu.
This will pull down any new information about additional bindings and stuff from the server side and update your client side config accordingly.
Once that's done, you should have multiple client side endpoints in your config and you can create whichever one of those is appropriate for your current needs based on the client endpoint name.

Related

WCF - Application is using client's app.config rather than WCF service's app.config

In my VS solution, I created a console project, which I'm using as the client, and an empty project for the WCF service.
I then created the WCF service (created my contract and service type and manually constructed the app.config), and added a reference to the WCF service project in the client project.
However, when I called ServiceHost.Open() in the client, the endpoints weren't loading. I eventually determined that I needed to put all of the config information in the Client's app.config, rather than the service's app.config.
I'm not sure if this is normal, or if I'm doing something wrong. In the past, when I've used the WCF project template, this wasn't the case.
Yes, that is normal. Each .NET application (client, service, web site, etc.) has it's own configuration file. To be precise, there's a hierarchy of them, but the bottom end of that hierarchy is unique to the application.
This makes sense if you think about it -- the client would need to contact the service to ask for it's configuration, but it needs to know the endpoint information in order to even try to do that. So yes, the normal process is that client and service both have very similar information in their configuration files.
If you use Visual Studio's built-in tooling to do everything for you, it will automatically create and/or edit the configuration file for your client when you add a Service Reference to the project, copying from the metadata endpoint that WCF exposes for that purpose. Alternatively, you can use the WCF configuration editor tools to edit your client application.
Also, note that nothing actually enforces that your client and server have compatible settings; e.g. you can change the maximum sizes of many buffers/graphs/etc on one side, and not the other, and see some strange behavior. It's up to you to make sure both ends are working with mutually usable settings.

Referencing WCF Services without mex binding

I was wondering how a client project in Visual Studio could reference a WCF service that doesn't have a mex binding. Whenever I remove the default mex binding in any sample WCF service, the client apps cannot find the service and in the auto-generated comments, it's recommended that in production environment, mex binding should be removed. Then how are the client apps supposed to find the service and reference it?
If you have access to the assemblies which contain the types which define the service contract, operations, and data contracts, then you can just create a proxy on the fly using ChannelFactory. In this instance you would not need to retrieve any service metadata as you already have access to all the information you need to call the service.
For example
// Create service proxy on the fly
var factory = new ChannelFactory<IMyServiceContract>("NameOfMyClientEndpointInConfigFile");
var proxy = factory.CreateChannel();
// Create data contract
var requestDataContract = new MyDataContract();
// Call service operation.
var responseDataContract = proxy.MyServiceOperation(requestDataContract);
It also helps if you have access to the service-side config file so you can copy the endpoint details out of there into your client config.
The mex endpoint is a necessary part of WCF SOAP services. It is what enables client toolkits to pull down the WSDL and auto-generate proxy classes. As you point out, without it, clients have no way to get the information to consume the service. If you want clients to be able to consume and find your service, you should leave it available when your service is in production.

Create WCF endpoint configurations in the client app, in code?

I am trying to consume a WCF web service from a .NET client application, and I think I need to be able to programmatically create endpoints, but I don't know how. I think I need to do this because, when I try to run the application, I am getting the following error:
Could not find default endpoint
element that references contract
'IEmailService' 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.
While troubleshooting this error, I created a simple windows forms application, in which I try to consume the same web service. With this test application I can connect to the web service successfully, and I get a valid response. But, I can reproduce the exact error cited above within in my test app by removing the system.serviceModel node and all of its child nodes from the application's app.config file (I might not have to remove ALL of that section, I'm not sure). So, my first thought was that I need to add that section to the app.config file for the real app, and everything should be fine. Unfortunately, for ridiculous reasons that I won't get into here, that is not an option. So, I am left with having to generate this information in code, inside the client app.
I am hoping someone here can help me work through this, or can point me toward a good resource for this sort of problem.
Is it possible to create endpoint configurations in the client app, in code?
By default, when you do an Add Service Reference operation, the WCF runtime will generate the client-side proxy for you.
The simplest way to use it is to instantiate the client proxy with a constructor that takes no parameters, and just grab the info from the app.config:
YourServiceClient proxy = new YourServiceClient();
This requires the config file to have a <client> entry with your service contract - if not, you'll get the error you have.
But the client side proxy class generated by the WCF runtime also has additional constructors - one takes an endpoint address and a binding, for instance:
BasicHttpBinding binding = new BasicHttpBinding(SecurityMode.None);
EndpointAddress epa = new EndpointAddress("http://localhost:8282/basic");
YourServiceClient proxy = new YourServiceClient(binding, epa);
With this setup, no config file at all is needed - you're defining everything in code. Of course, you can also set just about any other properties of your binding and/or endpoint here in code.
An east way to consume a WCF service if you have a reference to the assembly which defines the interface, is using the System.ServiceModel.ChannelFactory class.
For example, if you would like to use BasicHttpBinding:
var emailService = ChannelFactory<IEmailService>.CreateChannel(new BasicHttpBinding(), new EndpointAddress(new Uri("http://some-uri-here.com/));
If you don't have a reference to the service assembly, then you can use one of the overloaded constructors on the generated proxy class to specify binding settings.

How to create Endpoints from app.config file in WCF?

I have a service which has one endpoint , I have defined this endpoint in app.config file.
I want to know how can I create endpoints if I have app.config in program.
Please give me an idea.
Do you have a generated proxy for your service? If so, just use the proxy client!
MyServiceClient proxy = new MyServiceClient();
Optionally, you can pass in a name for the configuration to use:
MyServiceClient proxy = new MyServiceClient("MyConfigName");
No need to do anything fancy.
If you haven't created a proxy (using "Add Service Reference" in Visual Studio or svcutil.exe on the command line), you'll need to add a reference to your assembly containing the service and data contracts, and then use
ChannelFactory<IMyService> factory = new ChannelFactory<IMyService>();
IMyService proxy = factory.CreateChannel( );
Again, for creating the channel factory, you can pass in a name of a configuration section, if you have multiple, to specify which one to use.
Also, to clarify - a client can only ever have one endpoint at any given time. The service might have multiple - but the client needs to make up its mind and connect to exactly one of those - you cannot have multiple endpoints in a client (as the title of your questions appears to imply).
Marc
If you are using Visual Studio use the WCF Service Configuration Editor (found under tools). Use this to open your config file or hosted service and then you can create your endpoints there. Any new endpoint configuration info will be saved into your app.config/web.config as appropriate

Converting ASMX to WCF Web Service

I need to upgrade our web services to use WCF instead of ASMX. If the signatures of the web services stays the same, will existing clients that already call the ASMX service have to change anything on their end? Is there anyway to still use WCF but not force them to change anything?
Option 1 :
Using the current ASMX's WSDL, generate the client using svcutil.exe
Grab the generated interface and create a WCF service based on this interface
Output : One new WCF endpoint configured with basicHttpBinding. Clients need to update the URL at which they're sending the messages.
Option 2 :
Refactor your ASMX code. Move all the logic into a separate DLL.
Create a WCF service and use the logic in the refactored DLL.
Output : 2 endpoints, one for ASMX and another one for WCF
If you use the BasicHttpBinding for your new WCF service, and implement the same methods with the same message structure, existing callers should be able to call into this new WCF service without any change on their part.
There's also an AspNetCompatibilityRequirements attribute in order to get around some potential compatibility issue - see the MSDN documentation on it.
Marc