How to expose a single WCF service with multiple service behaviours? - wcf

I have a WCF service which needs to meet the following requirement:
Endpoint1 : It should use netTCP binding with windows authentication.
Endpoint2 : It should use netTCP binding with Custom User name and password validation.
I was able to do both of these individually by creating two service behaviors, one for Windows authentication and one for user name and password, but this way I have to expose 2 service instead of 1 for the above functionality. I am looking for a way by which I could expose only one service and by different end point configuration, I am able to fulfill the requirement.
Code snippet and configuration would be helpful.

This is one of the scenarios that WCF supports, a single interface exposed as 2 different endpoints.
They will have two different addresses, but will point to the same code.
<service
name="Microsoft.ServiceModel.Samples.CalculatorService"
behaviorConfiguration="CalculatorServiceBehavior">
<!-- This endpoint is exposed at the base address provided by host: http://localhost/servicemodelsamples/service.svc -->
<endpoint address=""
binding="basicHttpBinding"
contract="Microsoft.ServiceModel.Samples.ICalculator" />
<!-- secure endpoint exposed at {base address}/secure: http://localhost/servicemodelsamples/service.svc/secure -->
<endpoint address="secure"
binding="wsHttpBinding"
contract="Microsoft.ServiceModel.Samples.ICalculator" />
...
</service>
See: http://msdn.microsoft.com/en-us/library/ms751515.aspx

Related

WCF Single Service Implemation - Multiple Behaviours

I have an IIS hosted WCF service that I need to expose to two client types, external (basicHttp legacy) and internal (wsHttp WCF). For the external client I want to impose a more strict throttling configuration. It seems that the throttling config such as:
<serviceThrottling
maxConcurrentCalls="30"
maxConcurrentSessions="1000"
maxConcurrentInstances="30" />
can only be applied as a service behavior and not as an endpoint behavior. This means that I'll need to create two separate .svc files, which would resolve to the same .cs file, such as follows:
<service behaviorConfiguration="x.xServiceBehavior">
<endpoint
address="~/xService.svc"
binding="wsHttpBinding"
contract="xService.IxService"/>
</service>
<service behaviorConfiguration="xService.ThrottledxServiceBehavior">
<endpoint
address="~/ThrottledxService.svc"
binding="basicHttpBinding"
contract="x.xService.IxService"/>
</service>
Is that the best way to achieve what I'm after or is there an better way?
Thanks
Rob.
The way you have done it looks correct to achieve a different service behaviorConfiguration for the two different bindings. It may be possible to achieve the same effect while avoiding having two .svc files, but the way above will work fine so why rock the boat! :)

wcf endpoint relative address

I'm just learning wcf and can't understand one very basic thing.
I'm creating a WCF service which I want to be hosted in IIS just like web application with it's own path like http://myhost/myapp/ and everything.
I'm creating the WCF service project in VS, I've got an *.svc file describing it, then I define a simple endpoint to it like that:
<endpoint address=""
binding="basicHttpBinding"
contract="wcf_service_auth.IPshService" />
Then I publish this service like an IIS web application to a virtual directory, let's assume it's name psh_pub, so I can access the service via url http://localhost/psh_pub/pshservice.svc/. It shows me WCF greetings page and gives me a link to WSDL, which gives me correct wsdl description.
That's ok.
The next step - I want to add a MEX endpoint. I add to config:
<endpoint address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange"/>
That's ok too, the endpoint is accessible at address http://localhost/psh_pub/pshservice.svc/mex and WcfTestClient.exe gives me correct config from that url.
Here the problem comes.
I have a WCF service working under IIS and I want to add one more endpoint to it. For example let it be a net.tcp endpoint. The IIS is configured by default to accept net.tcp connections at port 808 and I'm adding net.tcp protocol to properties of my web app, and I want to add an endpoint to my service like that:
<endpoint address=""
binding="netTcpBinding"
contract="wcf_service_auth.IPshService" />
and now I assume that my service should be accessible via the url net.tcp://localhost:808/psh_pub/pshservice.svc. But it's not. And every "how-to" and manual on the web tells that I should specify full address in the config file like that:
<endpoint address="net.tcp://localhost:808/psh_pub/pshservice.svc"
binding="netTcpBinding"
contract="wcf_service_auth.IPshService" />
And if I do so, it works. But if host the service in another virtual directory, I'll need to change the config. If I host it on the other server, I'll need to change config. If I host it on multiple servers, I'll have to maintain as many configs as servers I have.
So the main questions is:
Is there any way in WCF to specify a net.tcp (or https) endpoint of a IIS-hosted WCF service without specifying absolute url for it?
You should be able to define a base address for your net.tcp service endpoints:
<service name="YourServiceName">
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:808/psh_pub/" />
</baseAddresses>
</host>
Then you should be able to use relative addresses in your actual endpoints:
<endpoint name="Tcp01"
address="pshservice.svc"
binding="netTcpBinding"
contract="wcf_service_auth.IPshService" />
</service>
WCF file-less activation (.Net 4.0) will let you register under a relative virtual path using the relativeAddress attribute:
<system.serviceModel>
<serviceHostingEnvironment>
<serviceActivations>
<add relativeAddress="relative-virtual-path/yourservice.svc"
service="YourServiceImpl" />
</serviceActivations>
</serviceHostingEnvironment>
</system.serviceModel>
relative to the base address of the Web application
This link talks about it: http://msdn.microsoft.com/en-us/library/ee354381.aspx

What kinds of non-HTTP addresses are allowed in WCF endpoints?

I'm just trying to save time by not learning about IIS and WAS, so I made a console application to host my WCF service. However, that leaves me uncertain as to how to specify an endpoint address that is not an HTTP address. Could the following config be the source of my runtime error? The exception description was: Could not find a base address that matches scheme http for the endpoint with binding WSHttpBinding. Registered base address schemes are [].
<system.serviceModel>
<services>
<service name="WcfService1.Service1">
<endpoint
contract="WcfService1.IService1"
binding="wsHttpBinding"
address="c:\users\owner\documents\visual studio 2010\projects\wcftest\wcfservice1\wcfservice1\service1.svc"/endpoint>
</service>
</services>
The word you're looking for is bindings. You change the binding attribute to match a binding that supports your desired protocol. For a simple console service host, I'd probably start with the netTcpBinding, which allows binding to an ipaddress:port combination.
Example:
net.tcp://localhost:8000/myservice

Dynamic WCF base addresses in SharePoint

I'm attempting to host a WCF service in SharePoint. I have configured the service to be compatible with ASP.NET to allow me access to HttpContext and session information
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
public class MISDataService : IMISDataService { ... }
And my configuration looks like this
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
<services>
<service name="MISDataService">
<endpoint address="" binding="webHttpBinding" contract="MISDataViews.IMISDataService" />
</service>
</services>
</system.serviceModel>
Whilst this gives me access to the current HTTP context, the serivce is always hosted under the root domain, i.e. http://www.mydomain.com/_layouts/MISDataService.svc.
In SharePoint the URL being accessed gives you specific context information about the current site via the SPContext class. So with the service hosted in a virtual directory, I would like it to be available on mulitple addresses e.g.
http://www.mydomain.com/_layouts/MISDataService.svc
http://www.mydomain.com/sites/site1/_layouts/MISDataService.svc
http://www.mydomain.com/sites/site2/_layouts/MISDataService.svc
so that the service can figure out what data to return based upon the current context.
Is it possible to configure the endpoint address dynamically? Or is the only alternative to host the service in one location and then pass the "context" to it some how?
Not a WCF specialist, but can't you specify the endpoint while connecting to the service?

Multiple WCF service of the same service and contract type

Is it possible to host 2 WCF services of the same type and contract on the same AppDomain?
In the configuration below, I am configuring a single service of type Service.SomeService that implements contract ISomeService. what I want to do is be able to host 2 services of this type, of course with different URIs.
<system.serviceModel>
<services>
<service name="Service.SomeService">
<endpoint address="net.tcp://localhost:8000/SomeService"
binding="netTcpBinding"
contract="Service.ISomeService" />
</service>
</services>
I am also self hosting these services in a windows service.
Thanks.
Yes, a Windows Service can host Multiple WCF Services. Each WCF service must have a unique address however. When you add endpoints to a ServiceHost instance, you must specify a unique address for each end point, which means you must vary atleast one of the scheme (net.tcp, net.pipe, http, etc), domain, port or path.
So basically I should be able to do this by adding multiple endpoints to a service:
<services>
<service name="Service.SomeService">
<endpoint address="net.tcp://localhost:8000/SomeService1"
binding="netTcpBinding"
contract="Service.ISomeService" />
<endpoint address="net.tcp://localhost:8000/SomeService2"
binding="netTcpBinding"
contract="Service.ISomeService" />
</service>
I appears that service type and contract in the configuration file should be unique. But is it possible to instead add 2 services of the same type and contract instead of adding 2 endpoints to the same service?
I appears that service type and
contract in the configuration file
should be unique.
Why? They don't have to be unique - no way. What has to be unique is the address (the complete one) for the service endpoint - of course, how else would WCF know where to send certain requests?
But is it possible to instead add 2
services of the same type and contract
instead of adding 2 endpoints to the
same service?
Sure, no problem:
<services>
<service name="Service.SomeService">
<endpoint address="net.tcp://localhost:8000/SomeService1"
binding="netTcpBinding"
contract="Service.ISomeService" />
</service>
<service name="Service.SomeOtherService">
<endpoint address="net.tcp://localhost:8000/SomeService2"
binding="netTcpBinding"
contract="Service.ISomeOtherService" />
</service>
</services>