WCF Multiple Services - same backing class, different service behavior - wcf

I have a single service, one backing binary, that I want to configure to have two different endpoints. The problem is, I want a different serviceBehavior for each endpoint, to specify different security requirements.
E.G:
<service behaviorConfiguration="behavior1" name="MyServiceClass">
<endpoint address="endpoint1" bindingConfiguration="binding1" contract="IMyServiceContract"/>
</service>
<service behaviorConfiguration="behavior2" name="MyServiceClass">
<endpoint address="endpoint2" bindingConfiguration="binding2" contract="IMyServiceContract"/>
</service>
Is such a WCF configuration valid, or attainable in another format?

I'm not sure you can do it from config only, but there exists a code and config solution based around the extensibility point exposed by the IEndpointBehavior interface. This allows you to define behaviors at the endpoint level.
It's not particularly well documented as I don't think it's used very often. According to MSDN:
Endpoint behaviors, which implement IEndpointBehavior, are the primary
mechanism by which you modify the entire service or client run time
for a specific endpoint.
There are two mechanisms for adding endpoint behaviors to a service.
Add the behavior to the Behaviors property.
Implement a custom BehaviorExtensionElement that extends
configuration.
Specific examples of the first option exist here, and here, but I can't find anything about the second.

Related

WCF - Is the services element mandatory

I think my question is rather simple, so I'll stick to the point:
Is it by any means possible to expose a service without specifying the services element and only the serviceHostingEnvironment element? I.e. would the below configuration be enough to host a WCF service? I'm asking because i've seen applications that - as far as I can tell - lack the services element, and I thought that was mandatory.
<serviceHostingEnvironment multipleSiteBindingsEnabled="true">
<serviceActivations>
<add relativeAddress="Service.svc" service="Namespace.To.My.Service" />
</serviceActivations>
</serviceHostingEnvironment>
With WCF 4.0 you don't need explicit service configuration as opposed to prior versions. It automatically adds default endpoints if no endpoints are defined explicitly.
Whatever configuration you mentioned in question is called File-less activation and you can activate service without even having physical .svc file. In WCF 4 you can define virtual service activation endpoints like one you have defined.
WCF detects what contracts are implemented by service and then method AddDefaultEndpoints adds one default endpoint per base address for each service contract implemented by the service. Note that this behavior is only when no explicit endpoints are added (either programmatically or through configuration). Should you add one explicit endpoint WCF stops adding default endpoints and it gives control to developer to customize it further.

Service vs Client nodes/sections in Web.Config

What is the difference between the Service node/section and the Client node/section in the configuration section? Why configure endpoints in one section over the other? Which is best for interoperability?
I'm currently building a service that talks to another service. I have endpoints for my clients and endpoints for the other service. Visual Studio seems to lump all the endpoints into the Client section.
I thought that client node was for your consumption and service node was for producing. But when you create a new wcf service visual studio puts your new service endpoint settings under the client node. I have moved my endpoint between both sections trying to figure out what the difference is.
When should I use service over client?
<system.serviceModel>
<services>
<service> <!--I noticed some tutorials and using wcf config edit tool
puts producer endpoint settings here -->
<endpoint blah settings/>
<endpoint blah settings/>
</service>
</services>
<client> <!--Visual Studio puts both producer and consumer endpoint
settings here -->
<endpoint blah settings />
<endpoint blah settings />
<endpoint blah settings />
</client>
<bindings>.....
</system.serviceModel>
Many settings in the WCF web.config (or app.config for that matter) can be shared for both consumers of a service as well as publishers of a service including:
Bindings
Endpoint Behaviors
Diagnostics
However as you have discovered, some config is specific to a service. A well-written service usually specifies:
It's base address. This is a convenience when defining a service as it allows your to define endpoints using relative addresses. Clients however don't use this particular setting as they need an absolute path. For this reason it makes no sense to specify in the section
Services can also be clients. If the client and server endpoints were all plonked together, WCF would not be able to know which should utilise the base address for one thing
Service behavior
By dividing up config between client and server, WCF is better able to know where to look for endpoints.
Which is best for interoperability?
I don't think that has anything to do with it. WCF is a means to achieve interopability but just by using WCF does not imply you will achieve it. Interopability is established when both parties agree on say a particular service contract; canonical data model; data transformation; message version or many of the other patterns as defined by SOA Patterns.org So there are various patterns you must follow. e.g. If you change a method on service contract but have not updated the clients then you have broken interopability by breaking the schema of the service.
Visual Studio seems to lump all the endpoints into the Client section
If your WCF process is both a consumer and producer of WCF services then it should not be putting all the endpoints under

Single WCF REST service with multiple behaviours

Is it possible to create a WCF REST 4.0 service which has two endpoints with different behaviours? Specifically I’m looking for one endpoint to use transferMode=Streamed, and the other to use Buffered.
I’ve started off using the WCF REST Service Application, which seems to be a mix of WCF and ASP MVC routing technologies. I can set transferMode for both endpoints in
system.serviceModel/standardEndpoints/webHttpEndpoint/standardEndpoint
but am not having any joy applying additional ones to my routes.
I’m not quite clear where the WCF/MVC separation exists, for example whether the Global.asax counts as one WCF endpoint or whether the routes are individual endpoints, and as a result am not sure how to progress.
Is there a simple Web.config change or attribute I can apply to a service to specify different behaviour?
If not, can I create separate asax files using different behaviours instead of one Global.asax file?
If not, should I create .svc files to map onto my classes as in a normal WCF application?
If not, will I have to create a second project to define different behaviour?
Each service route creates a new ServiceHost. Also, REST Starter Kit is now deprecated, either you should use straight WCF REST 4.0, or you should look into the new WCF Web API stuff at http://wcf.codeplex.com
What about doing it that way:
<services>
<service name="YourNamespace.YourServiceClass">
<endpoint address="stream" kind="webHttpEndpoint" endpointConfiguration="webHttpStreamed" contract="YouServiceContract" />
<endpoint address="buff" kind="webHttpEndpoint" endpointConfiguration="webHttpBuffered" contract="YouServiceContract" />
</service>
</services>
<standardEndpoints>
<webHttpEndpoint>
<standardEndpoint name="webHttpStreamed" transferMode="Streamed" />
<standardEndpoint name="webHttpBuffered" transferMode="Buffered" />
</webHttpEndpoint>
</standardEndpoints>
Of course, the two endpoints' addresses must not be overlapping.

All about WSDL vs MEX?

I am not able to open the meta data url http://localhost:8082/Tasks/mex, even though
I've added the mexHttpBinding in the config file. Can I view this MEX endpoint in a browser?
The config files look like:
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
Questions:
Is MEX is different from WSDL? If not, then why do we require a MEX endpoint over WSDL?
In the WSDL, I see the WSDL type information is missing. Is it by default? Can I look at the type information in WSDL?
Check out serviceMetadata for more information regarding the WCF configuration file.
To answer your questions though, MEX is a newer W3C standard for the presentation of Service description information; WSDL was the previous method. If you need to allow older clients to access your service description information, you may have to expose that information via WSDL.
The information for exposing your service description information as WSDL (httpGetEnabled) is also in the link provided above.
Also, try using the wcftestclient.exe to access your WCF service. It provides more functionality and information than a browser.
Aakash, Did you add a service behavior with a <serviceMetadata> element? It can be empty, i.e. <serviceMetadata />, but it must be present. The service definition needs to reference the service behaviorConfiguration. Check out the following for examples:
http://www.request-response.com/blog/PermaLink,guid,c9513d28-f580-4a33-b4e8-c15476799a9d.aspx
If you look at that endpoint, you'll see it looks like every other endpoint. There's even a service contract (IMetadataExchange). You can look at System.ServiceModel.Description.IMetadataExchange and see what that contract is all about.

How many ServiceContracts can a WCF service have?

How many ServiceContracts can a WCF service have?
Specifically, since a ServiceContract is an attribute to an interface, how many interfaces can I code into one WCF web service? Is it a one-to-one?
Does it make sense to separate the contracts across multiple web services?
WCF services can have multiple endpoints, each of which can implement a different service contract.
For example, you could have a service declared as follows:
[ServiceBehavior(Namespace = "DemoService")]
public class DemoService : IDemoService, IDoNothingService
Which would have configuration along these lines:
<service name="DemoService" behaviorConfiguration="Debugging">
<host>
<baseAddresses>
<add baseAddress = "http://localhost/DemoService.svc" />
</baseAddresses>
</host>
<endpoint
address =""
binding="customBinding"
bindingConfiguration="InsecureCustom"
bindingNamespace="http://schemas.com/Demo" contract="IDemoService"/>
<endpoint
address =""
binding="customBinding"
bindingConfiguration="InsecureCustom"
bindingNamespace="http://schemas.com/Demo" contract="IDoNothingService"/>
</service>
Hope that helps, but if you were after the theoretical maximum interfaces you can have for a service I suspect it's some crazily large multiple of 2.
You can have a service implement all the service contracts you want. I mean, I don't know if there is a limit, but I don't think there is.
That's a neat way to separate operations that will be implemented by the same service in several conceptually different service contract interfaces.
#jdiaz
Of course you should strive to have very different business matters in different services, but consider the case in which you want that, for example, all your services implement a GetVersion() operation. You could have a service contract just for that operation and have every service implement it, instead of adding the GetVersion() operation to the contract of all your services.
A service can theoretically have any number of Endpoints, and each Endpoint is bound to a particular contract, or interface, so it is possible for a single conceptual (and configured) service to host multiple interfaces via multiple endpoints or alternatively for several endpoints to host the same interface.
If you are using the ServiceHost class to host your service, though, instead of IIS, you can only associate a single interface per ServiceHost. I'm not sure why this is the case, but it is.