Most of the WCF examples out there show you how to configure WCF client and server. Now, what happens if you differ the configuration slightly between them? I mean, who has the
If a given timeout is about the same thing in the end, on the client and the server, and the two values don't match, the shorter timeout "wins" - no matter whether it's defined on the server or the client.
Most other things like addresses, bindings etc. must match - otherwise, no communication will be possible...
The benefit of the server setup is that you can define multiple endpoints for a single service, with different options and bindings - and the client can then "pick and choose" which endpoint to connect to.
But once one service endpoint has been chosen for your connection, the settings like bindings, protocols, security, reliability and so forth must match exactly.
Also: the default config that the Visual Studio Add Service Reference
or the svcutil.exe
command line tools generate are both catastrophically bad - they contain way too many settings that all reflect the default values, which make it really hard to know what's really needed and what is not.
In that respect, I'd recommend watching the DotNet Rocks TV Show #122: Miguel Castro on Extreme WCF in which Miguel nicely shows just how easy it really is to create those configs manually, and then you completely understand what the heck you're doing! Highly recommended!
In order to address your request in your last comment to my previous answer, I tried to come up with my approach to how I would create (and modify) server- and client-side config's for any given service. This is based on both theory I read (books, blogs), things I've learned in Juval Lowy's WCF Master Class
, and quite a bit of practical experience with several large service implementation projects - this isn't available in one single place, on the web or in a book.... so here it goes:
I would start basically from scratch. Think about your service first:
Simplest scenario: single service, single endpoint, basicHttpBinding, all defaults
Service config:
<system.serviceModel>
<services>
<service name="YourNamespace.YourServiceClass">
<endpoint name="Default"
address="http://YourServer/SomeVirtualDirectory/YourService.svc"
binding="basicHttpBinding"
contract="YourNamespace.IYourServiceContract" />
</service>
</services>
</system.serviceModel>
Corresponding client config:
<system.serviceModel>
<client name="Default">
<endpoint name="Default"
address="http://YourServer/SomeVirtualDirectory/YourService.svc"
binding="basicHttpBinding"
contract="YourClientProxyNamespace.IYourServiceContract" />
</client>
</system.serviceModel>
Then only ever change something if you really must! And most of all: NEVER EVER let Visual Studio (Add Service Reference) or svcutil.exe
screw up your config! Protect it like the apple of your eye!
Then: if e.g. your data transfer takes more time than the default timeout of 1 minute allows, change that one single setting on both the service side and the client side. Do this by defining a custom binding configuration and referencing that from your endpoints - but change only that - not more! Leave everything else as is, with default values. Don't ever change anything unless you absolutely must (and know what you're doing, and why you're doing it).
Mind you: the sendTimeout
on the client (time allowed until the whole message has been sent) will correspond to the receiveTimeout
on the server - the time allowed for the whole message to come in (see this excellent blog post and this MSDN forum thread for more information)
Service config:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="ExtendedTimeout"
receiveTimeout="00:05:00" />
</basicHttpBinding>
</bindings>
<services>
<service name="YourNamespace.YourServiceClass">
<endpoint name="Default"
address="http://YourServer/SomeVirtualDirectory/YourService.svc"
binding="basicHttpBinding"
bindingConfiguration="ExtendedTimeout"
contract="YourNamespace.IYourServiceContract" />
</service>
</services>
</system.serviceModel>
Corresponding client config:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="ExtendedTimeout"
sendTimeout="00:05:00" />
</basicHttpBinding>
</bindings>
<client name="Default">
<endpoint name="Default"
address="http://YourServer/SomeVirtualDirectory/YourService.svc"
binding="basicHttpBinding"
bindingConfiguration="ExtendedTimeout"
contract="YourClientProxyNamespace.IYourServiceContract" />
</client>
</system.serviceModel>
As you need other changes, like multiple endpoints on the service side, or local settings like bypassProxyOnLocal
- adapt your config, do it carefully, step by step, manually, and consider your config an extremely essential part of your whole service - take care of it, put it in version control etc.