Using 2 WCF interfaces in the same svc file - wcf

We are trying to communicate with an external WCF service.
The WCF services are exposed via svc files. It appears that there are 2 interfaces exposed via the same svc file.
How can we configure this in the web.config file?

If I understand your question correctly, you have a single class that implements 2 WCF service contracts. In your web.config, you configure an endpoint for each service contract, but under the same <service> node. I've only done this when self-hosting WCF services, not in IIS, but I think if you specify a value for address in your endpoint configuration, it will make it relative to the location of the .svc file:
<service name="YourServiceLibrary.YourServiceClass">
<endpoint address="Service1"
contract="YourServiceLibrary.IService1"
...
/>
<endpoint address="Service2"
contract="YourServiceLibrary.IService2"
...
/>
</service>
You would then setup your client proxies for each service contract to point to http://YourServer/YourServicePath/YourServiceClass.svc/Service1 and http://YourServer/YourServicePath/YourServiceClass.svc/Service2

Related

How can I programmatically create an endpoint and use it in my service instead of obtain it from the web.config?

Basically I want to create this binding that will listen to azure service bus queue:
<services>
<service name="myServiceName">
<endpoint address="sb://****.servicebus.windows.net"
listenUri="sb://****.servicebus.windows.net"
binding="netMessagingBinding"
bindingConfiguration="netMessagingBinding"
behaviorConfiguration="myConfiguration"
name="myServiceEndpoint"
contract="****" />
</service>
I also need to know how I can use it in my service.
Look at your servicehost file (.SVC) it can contain a reference to the factory class that generates your service file. More info here: http://msdn.microsoft.com/en-us/library/aa967286.aspx
By providing your own factory you get an ability to override the generation of your service class via CreateServiceHost method. That will give you more control as to how your service class is created. You can inject your own URL's,l etc.
HTH

How to configure WCF service from code when hosted in IIS?

My WCF service exposes an https AND an http endpoint. Apart from the SSL they are identical. They map to the same code.
The ultimate intention is for external users to connect via https, internal users to use http.
In development this gives me a problem. Cassini, the development web server packaged in VS, hates SSL.
I'm wondering if I can configure the service from code, so when running under Cassini, I would not configure https.
Hence the question - How do I configure the service from code if it is IIS hosted? I'd be very happy with alternative answers on how I can persuade Cassini to NOT complain about the https part of the configuration.
"IIS will take care of spinning up the necessary ServiceHost based on your *.svc file - not a whole lot you can do about that, really."
Not too close to the truth. Exactly in the SVC file of your service there is attribute named Factory. Where you can specify the the class and the assebly where the class is located. This class may be your own descendant of Web|DataServiceHostFactory
So your svc markup would look like this
<%# ServiceHost
Language="C#"
Debug="true"
Service="name.space.myService"
CodeBehind="name.space.myService.svc.sc"
Factory = "name.space.WebServiceHostFactoryEx, assembly.name"
%>
The WebServiceHostFactory will be created for every service hit and will recreate your host the way you want it.
You will also need to inherith WebServiceHost and create it the way you need it with certain endpoins, behaviors, addresses, etc settings - whatever you like.
There is very nice post from Michele Bustamante here
EDIT: I figured out the above link is not working anymore, so here it is another one.
I am using this in IIS hosted enviroment for couple of services that are initialized same way.
When you're hosting in IIS, you're leaving a lot of care taking into the realm of IIS - you cannot really grab a hold of your service in this case.
IIS will take care of spinning up the necessary ServiceHost based on your *.svc file - not a whole lot you can do about that, really.
My solution would be different - externalize the <service> tag in your configuration file (web.config):
<system.serviceModel>
<services>
<service configSource="service.dev.config" />
</services>
</system.serviceModel>
In your dev environment, only expose the http endpoint - so your service.dev.config would look something like this:
<service name=".....">
<endpoint name="default"
address="....."
binding="basicHttpBinding" bindingConfiguration="insecure"
contract="......" />
</service>
Create a second service.prod.config which then contains both endpoints - http and https:
<service name=".....">
<endpoint name="default"
address="....."
binding="basicHttpBinding" bindingConfiguration="insecure"
contract="......" />
<endpoint name="secure"
address="....."
binding="basicHttpBinding" bindingConfiguration="secure"
contract="......" />
</service>
and reference that in your web.config on the deployment server.

WCF - remote service without using IIS - base address?

I'm trying to get my head around the addressing of WCF services.
We have a client-server setup where the server occasionally (maybe once a day) needs to push data to each client. I want to have a lightweight WCF listener service on each client hosted in an NT service to receive that data. We already have such an NT service setup hosting some local WCF services for other tasks so the overhead of this is minimal.
Because of existing legacy code on the server I believe the service needs to be exposed as ASMX and use basicHttpBinding to allow it to connect.
Each client is registered on the server by the user (they need to configure them individually) so discovery is not the issue.
My question is, how does the addressing work? I imagine the user entering the client's address on the server in the form
http://0.0.0.0/MyService
or even
http://hostname/MyService
If so, how do I configure the client service in its App.config? Do I use localhost?
If not then what is the reccommended way of exposing the service to the server?
Note:
I don't want to host in IIS as that adds extra requirements to the hardware required for the client.
The clients will be almost certainly located on LANs, not over the public internet
You configure the base address of the service like so:
<system.serviceModel>
<services>
<service name="Ns.FooService">
<host>
<baseAddresses>
<add baseAddress="http://localhost:9999" />
</baseAddresses>
</host>
<endpoint
address="/foo"
binding="basicHttpBinding"
contract="Ns.IFooContract" />
</service>
</services>
</system.serviceModel>
And then your service could be accessible through http://servename:9999/foo. You may take a look at this article for more information.

dynamic refeences for WCF service

I have a WCF service hosted on IIS. I have a smartclient application which calls this WCF service through endpoints defined in app.config file.
Now when i publish this application using this configuration, IT throws an exception saying that no endpoint is listening at localhost.
How can i make it dynamic. By dynamic I mean IF i update the endpoint in app.config file the application should pick up that url instead of the url with which the application was published with.
I remember i could do it in webservices. Please help.
Your app.config would most likely contain something like:
<client>
<endpoint name="...."
address="........"
Check the address - that's the URL you're trying to connect to. You need to provide the server's address and port and path - no localhost, of course.
<client>
<endpoint name="...."
address="http://yourserver/yourVirtualDir/YourService.svc"
That should do the trick.
Marc

WCF Webservice behind public reverse proxy

How can I correctly serve WSDL of a WCF webservice located in a private LAN from behind a reverse proxy listening on public IP?
I have an Apache webserver configured in reverse proxy mode which listens for requests on a public IP address and serves them from the internal IIS host. WCF webservice generates WSDL using the FQDN address of the LAN host which, of course, cannot be read by an internet web service client.
Is there any setting that can be configured in wcf application's web.config or in IIS in order to customize the WSDL generated containing host address and put public address instead?
Add the following attribute to your service class:
<ServiceBehavior(AddressFilterMode:=AddressFilterMode.Any)>
This allows the service to be addressed by the client as https://... but the service can still be hosted on http://.....
See my answer on How to specify AddressFilterMode.Any declaratively for how to create an extension to allow AddressFilterMode.Any to be specified through configuration without requiring code attributes.
In the web.config of the service host, the endpoint element must have an absolute URL in the address attribute that is the public URL that will be used by the client. In the same endpoint element, set the listenUri attribute to the absolute URL on which the service host is listening.
The way I determine what the default absolute URI the host is listening on is to add a service reference in a client application which points the the physical server where the service is hosted. The web.config of the client will have an address for the service. I then copy that into the listenUri attribute in the hosts web.config.
In your service behavior configuration, add the element serviceMetaData with attribute httpGetEnabled=true
So you'll have something like this:
<serviceBehaviors>
<behavior name="myBehavior">
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
<!-- ... -->
<services>
<service name="NamespaceQualifiedServiceClass" behavior="myBehavior" >
<endpoint listenUri="http://www.servicehost.com"
address="https://www.sslloadbalancer.com"
binding="someBinding"
contract="IMyServiceInterface" ... />
</service>
</services>
I am not sure if this works with message security or transport security. For this particular application, the credentials were passed as part of the DataContract so we had basicHttpBinding > security > mode=none. Since the transport is secure (to the ssl load balancer) there were no security issues.
It is also possible in to leave the listenUri attribute blank, however it must be present.
Unfortunately, there is a bug in WCF where the the base address of imported schemas in the WSDL have the listenUri base address rather than the public base address (the one configured using the address attribute of the endpoint). To work around that issue, you need to create an IWsdlExportExtension implementation which brings the imported schemas into the WSDL document directly and removes the imports.
An example of this is provided in this article on Inline XSD in WSDL with WCF. Additionally you can have the example class inherit from BehaviorExtensionElement and complete the two new methods with:
Public Overrides ReadOnly Property BehaviorType() As System.Type
Get
Return GetType(InlineXsdInWsdlBehavior)
End Get
End Property
Protected Overrides Function CreateBehavior() As Object
Return New InlineXsdInWsdlBehavior()
End Function
This will allow you to add an extension behavior in the .config file and add the behavior using configuration rather than having to create a service factory.
Under the system.servicemodel configuration element add:
<behaviors>
<endpointBehaviors>
<behavior name="SSLLoadBalancerBehavior">
<flattenXsdImports/>
</behavior>
</endpointBehaviors>
</behaviors>
<extensions>
<behaviorExtensions>
<!--The full assembly name must be specified in the type attribute as of WCF 3.5sp1-->
<add name="flattenXsdImports" type="Org.ServiceModel.Description.FlattenXsdImportsEndpointBehavior, Org.ServiceModel, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
</behaviorExtensions>
</extensions>
And then reference the new endpoint behavior in your endpoint configuration using the behaviorConfiguration attribute
<endpoint address="" binding="basicHttpBinding" contract="WCFWsdlFlatten.IService1" behaviorConfiguration="SSLLoadBalancerBehavior">
I'm having similar issues, one of which was the resolution of public and server addresses. This solved that issue although I still have a couple authentication problems.
See: How to change HostName in WSDL for an IIS-hosted service? by Wenlong Dong
archive
See: Service Station WCF Addressing In Depth by Aaron Skonnard
archive link