Dynamic WCF base addresses in SharePoint - wcf

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?

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

Endpoint Address when Hosting in Window Service vs IIS

i have a Service with a Name MyService and It implements a Service Contract IMyService
when i am hosting in IIS i have added a SVC file and a Web.config and
provided the base address as
http://localhost:49495/MyService.svc/
Its working fine
Now i want to Host the same Service in a Windows Service and now i am confused what should i give in base address of App config of a Windows Service
should i give Class name MyWindowService Which Implement ServiceHost
like this base address :-
http://localhost:49496/MyWindowService/
The base address can be anything. As you are hosting it as an HTTP endpoint I would just make it exactly the same as your web version. The important bit of the configuration is as follows:
<service name="MyService">
<host>
<baseAddresses>
<add baseAddress="http://localhost:49495/MyService.svc"/>
</baseAddresses>
</host>
<endpoint address=""
binding="wsHttpBinding"
bindingConfiguration="WsHttpBinding"
contract="IMyService" />
</service>
the name is the concrete class implementation of the service contract and the contract is the interface (so MyService and IMyService in your example).
he rest is up to you - I personally don't think the client needs to care whether the service is hosted in a windows service or IIS so I would have the endpoint with the .svc so I can freely swap it around. As long as the URL stays the same and the binding configuration also you can host it how you like.

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

ISA Web Farm and WCF service hosted in a Windows Service with basicHttpBinding

I have created a WCF service that needs to be hosted in a Window Service because it is participating in a P2P mesh (NetPeerTcpBinding). When I tried to host the WCF Service with NetPeerTcpBinding endpoints in the IIS Service container the service wouldn't run because it turns out that the P2P binding doesn't work in IIS.
I have exposed a HTTP endpoint from the WCF service hosted in a Windows Service container and I want to know if there is a way to create an ISA Web Farm that will route traffic to http endpoints on two machines each running the same WCF service in a Windows Service container.
I figured this out quit a wile ago, sorry it took so long to get the answer posted.
Create a separate service contract called IDefaultDocumentService with one method on it that is decorated with both OperationContract and WebGet.
<OperationContract(), WebGet()>
Function GetDefaultDocument() As System.ServiceModel.Channels.Message
Now implement that contact in a very simple DefaultDocumentService class
Public Class DefaultDocumentService
Implements IDefaultDocumentService
Public Function GetDefaultDoc() As Message Implements IDefaultDocumentService.GetDefaultDocument
Return Message.CreateMessage(MessageVersion.None, "", "Hello!")
End Function
End Class
In the config file for you windows service hook up a separate service for the DefaultDocumentService and map it to the root directory of your other WCF service. When you are putting these services into a Web Farm on ISA it will hit your default document service and get a "Hello!" message which is enough for the ISA server to know that the service is alive.
<system.serviceModel>
<services>
<service name="YourMainService">
<endpoint address="http://localhost:10000/YourMainService.svc"
binding="wsHttpBinding"
contract="IYourMainService" />
</service>
<service name="DefaultDocumentService">
<endpoint address="http://localhost:10000/"
binding="webHttpBinding"
behaviorConfiguration="DefaultDocumentEndpointBehavior"
contract="IDefaultDocumentService" />
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="DefaultDocumentEndpointBehavior">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>