WCF Single Service Implemation - Multiple Behaviours - wcf

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! :)

Related

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

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

when using both the rest and soap end points. I need to make the soap as the default one?

I need to use soap end point as the default one because i dont need the existing users to be disturbed..what is the change that i should do in the config?
I have two end points one for soap and one for rest services. I tried creating two separate services but still didnt work
Here is a sample:
<endpoint address="json/mycontract" behaviorConfiguration="webBehavior" binding="webHttpBinding" contract="MyContract" />
<endpoint address="soap/mycontract" binding="basicHttpBinding" contract="MyContract" />
There is no such thing as a default endpoint from client point of view. The clients do consume the service contracts using the desired endpoints.

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

WCF URL Question

I'm somewhat new to web development, so I'm unsure of the terminology to use here. I have a wcf web service that I've build for windows azure. I would like to have multiple endpoints that resolve to the same service, however I'm not entirely sure how to configure this.
This may help explain what I'm wanting a little better:
Currently, I have a service at https://myapp.cloudapp.net/service.svc
I would like to have the following url point to the same service in the application:
https://myapp.cloudapp.net/myapp/service.svc
I'm sure this is something easy to do, I just haven't been able to find a solution yet.
Edit:
I found this documentation on MSDN:
http://msdn.microsoft.com/en-us/library/ms734786.aspx
However, I can't seem to get it to work.
Here is is how my endpoint is defined in my web.config:
<services>
<service behaviorConfiguration="MetadataEnabled" name="myProject.myApp.myService">
<host>
<baseAddresses>
<add baseAddress="https://localhost/myService/" />
</baseAddresses>
</host>
<endpoint address="" binding="wsHttpBinding" bindingConfiguration="wsBinding" name="wsBase" contract="myProj.myApp.IServ" />
<endpoint address="mex" binding="mexHttpsBinding" bindingConfiguration="mexBinding" name="HttpMetadata" contract="IMetadataExchange" />
<endpoint address="myApp/" binding="wsHttpBinding" bindingConfiguration="wsBinding" name="WsPlain" contract="myProj.myApp.IServ" />
</service>
</services>
It's still not working, but hopefully it's getting close. Would love any suggestions!
I just found out the answer. I just needed to create a folder in the project "myApp", and make copy the .svc file (not the .svc.cs file) to that folder. This allowed the following to work:
myapp.cloudapp.net/service.svc
myapp.cloudapp.net/myapp/service.svc
This is trivial and probably you already do, but are you defining InputEndpoints in ServiceDefinition.csdef?
There's a WCF Routing Service that might be of use (or might be overkill).
See also Supporting Multiple IIS Site Bindings and Endpoint Addresses.

WCF endpoints, baseAddressPrefixFilters, host headers

I have two websites on the same machine. The first (client) references a WCF service on the second site(server).
How do I set the address for the service reference? When moving from development on my local machine to the group development server, how do I change the url for the service? The sites are differentiated by host headers, like
http://dev.admin/...
and
http://dev.public/...
I sense that this can be handled using multiple endpoints, but I'm very new to WCF and really don't have a clue what I'm doing here.
After much frustration, I managed to determine that both web.config files (on the client and server, both of which are web apps in this case), the following sections have to be changed:
Client:
<client>
<endpoint
address="http://mysite.com:port/services/someservice.svc"
binding="basicHttpBinding"
bindingConfiguration="BasicHttpBinding_ISomeService"
contract="MyServices.ISomeService"
name="BasicHttpBinding_ISomeService" />
</client>
</system.serviceModel>
Server
<system.serviceModel>
<serviceHostingEnvironment>
<baseAddressPrefixFilters>
<add prefix="http://mysite.com:port/services"/>
</baseAddressPrefixFilters>
</serviceHostingEnvironment>
<behaviors>
<serviceBehaviors>
<behavior name="MyServices.SomeServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="MyServices.SomeServiceBehavior"
name="MyServices.SomeService">
<endpoint address="http://mysite.com:port/services/someservice.svc"
name="endpoint.SomeService"
binding="basicHttpBinding"
bindingConfiguration=""
contract="MyServices.ISomeService"/>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
</system.serviceModel>
The thing to note here is that the host address in all three relevant sections (client endpoint address, server baseAddressPrefixFilter value, and server endpoint address) have to match.
I'm able to switch between servers by modifying these, as long as they match. I would still prefer a way to set this based on which machine the server is running on, but this works for the moment.
WCF Impressions
What's hot: persistent object. The client proxy object (created when you add a service reference) maintains a persistent connection to the service on the server. The service instance referenced by the client proxy maintains its state between calls, which can simplify method signatures and makes the client proxy object, and the service as a whole, much more useful for certain applications. Parameter object types can be shared between the client and server if they're declared in a common library, meaning that you don't have to create two very similar classes or wrapper classes to pass non-primitive data structures back and forth.
What's not: configuration is a royal pain, poorly documented, and far too involved. Getting this to work in a test/dev/staging/production environment configuration where the service neesd to be aware of its location is frustrating. I'm not convinced that making the service aware of its domain url (rather than, say, a relative path to whatever it's running on) has any significant benefit, security concerns aside.
That said, I'm continuing to go down the WCF path as the advantages thus-far outweigh the headaches.
Easiest way: run the WCF parts on different ports.