WCF in IIS - Unique URLs per Cusomer - wcf

I'm replacing our old (VB.NET/asmx) service with WCF. We wanted to use WebAPI but have too many customers that still want SOAP. We'll be hosting in IIS 7. (.NET 4.5.2)
Each of our customers (~30) expects their own URL: https://www.example.com/API/4.0/ATT...whatever. I don't anticipate our customer count getting beyond 50 anytime soon.
I know I can accomplish this (as our old service did) by creating a .svc file for each client and (I believe) another endpoint in the config. But from what I've read I think this can be accomplished just through multiple endpoints for one service (the binding and contract/interface are all the same) and that seems much cleaner.
I've made a little progress on this but am running into problems. I'm not asking for help on those problems (yet!) - I'm asking: does anyone have input on whether this is a feasible (or the best?) approach before I dig farther?
Below is a snippet of the config file. I feel like I'm pretty close but if filtering/listenUri is wiser I'll switch tactics.
<service name="API" behaviorConfiguration="beUserNameBehavior">
<host>
<baseAddresses>
<add baseAddress="https://ww6.example.com/API"/>
<!--<add baseAddress="http://localhost:55375/"/>-->
</baseAddresses>
</host>
<endpoint name="BE" address="/BE" binding="wsHttpBinding" bindingConfiguration="beUserNameBinding" contract="API.IBEAPI" />
<endpoint name="SAP" address="/SAP" binding="wsHttpBinding" bindingConfiguration="beUserNameBinding" contract="API.IBEAPI" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>

Related

One WCF service listening to multiple addresses (config only)

I have an existing Windows service (so no IIS) which hosts a WCF-service.
At this moment it is listening one address: http://xxx/service.svc.
And now I want it to ALSO listen to a second address: http://yyy/service.svc.
I can only modify the configuration, not the sources. The service is running under .NET Framework 4.5.2.
My configuration:
<services>
<service behaviorConfiguration="All" name="MyNamespace.MyService">
<endpoint address="" binding="basicHttpBinding" bindingConfiguration="myBindingConfig" contract="MyNamespace.IMyService"/>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
<host>
<baseAddresses>
<add baseAddress="http://xxx/service.svc"/>
</baseAddresses>
</host>
</service>
</services>
What I have tried so far:
Added an extra base address. Then I get an exception: This collection already contains an address with scheme http.
Duplicated the service-element and modify the base address. Exception: A child element named 'service' with same key already exists at the same configuration scope.
If I change the name of both services: Service 'MyNamespace.MyService' has zero application (non-infrastructure) endpoints.
If have read about and tried serviceHostingEnvironment (as suggested in WCF service startup error "This collection already contains an address with scheme http") but only adding that snippet in, does not help. Maybe that is a half step forward, but then I need the second half of that solution.

WCF Service without Configuration

I have a wcf service (not self hosted).
When I deleted the section from web.config
<services>
<service name="Namespace.A">
<endpoint address="" binding="basicHttpBinding" name="A_EndpointBinding" contract="A" />
</service>
</services>
it works.
How could that be possible ? Does it occur any problem without that ?
If you can successfully connect and use the service (Namespace.A) using HTTP, then you should have nothing to worry about!
What's happening is either the above is misconfigured or its interfering with other settings and/or hard-coded functionality.

Wcf bindings difference while hosting on windows azure

I have wcf service application which i host on IIS and runs very well.
now i need to transfer the services to windows azure where i host them into web role.
i am not sure but i have heard that there are different bindings for windows azure
example:
azure has different bindings equivalent to basicHttp,WebHttp.
can i know what exactly i need to do to achieve the same.
here is my current service configuration
<service behaviorConfiguration="mybehavior" name="***">
<endpoint address="mobile" behaviorConfiguration="web" binding="webHttpBinding"
contract="*" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://127.0.0.1:81/Mobile.svc" />
</baseAddresses>
</host>
</service>
what change does this need
Thanks
You can achieve your goal with web.config transofmrations (and here). The issue with Azure is that there is no localhost, nor 127.0.0.1 there (well, there might be, but nothing is being routed to that local loop address). All you have to do is to change the baseAddress.
In order to change the baseAddress you may do any of the following:
use web.config transofmrations and in your web.Release.config put your azure domain name in the base address (http://yourapp.cloudapp.net/, or your custom domain if you are using one)
programatically bind the wcf service using the DIP of the role instance (check this and that questions for more information)

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 wsHttpBinding and BasicHttpBinding in same WCF Service Application

I have been told that wsHttpBinding does not support older clients that still need to use older version of SOAP. I want to add a BasicHttpBinding endpoint in the same WCF Service Application so that clients can use either endpoint depending on their technology they are running. I am confused as to what the address to use for each of them. The default wsHttpBinding has no address set. What should the address be for BasicHttpBinding endpoint? Shouldn't the address for the wsHttpBinding be (for my example) http://localhost/WcfService1/Service1.svc ?
There's two things you need to consider here:
if your hosting in IIS (or WAS as part of IIS7), you cannot set a base address - the base address for your service will be the virtual directory where the MyService.svc file lives. You can still set relative addresses, though
if you self-host, you typically will add base addresses in your config, so you can spare yourself having to spell out the entire address all the time (but you can - if you wish to do so).
So if you have your MyService.svc inside a virtual directory called MyApp on your localhost machine, and then use this config:
<service name="MyService" behaviorConfiguration="Default">
<endpoint
address="wsHttp"
binding="wsHttpBinding"
contract="IMyService" />
<endpoint
address="basic"
binding="basicHttpBinding"
contract="IMyService" />
</service>
then your "old-style" basicHttp service will be reachable at:
http://localhost/MyApp/MyService.svc/basic
and your new wsHttp driven service will be reachable at:
http://localhost/MyApp/MyService.svc/wsHttp
You can name those relative addresses (anything after .../MyApp/MyService.svc) anything you like - just make sure they're different from one another.
Hosting in IIS --> location (virtual directory) of your *.svc file becomes your base address.
If you self-host your service inside a console app or a Windows NT Service, you get to set your base addresses yourself:
<services>
<service name="MyService" behaviorConfiguration="Default">
<host>
<baseAddresses>
<add baseAddress="http://localhost:8185/Services/" />
</baseAddresses>
</host>
</service>
</services>
Now in this case, your "old-style" basicHttp service will be reachable at:
http://localhost:8185/Services/basic
and your new wsHttp driven service will be reachable at:
http://localhost:8185/Services/wsHttp
You can define a base address for each of the transports, e.g. one for http://, one for net.tcp:// and so on.
And of course, if you really must, you can also define your complete addresses inside your <endpoint> element for each of the service endpoints - this gives you total flexibility (but only works in self-hosting scenarios).
Marc
In WCF you have a base address and an enpoint address, in your case you can do something like this:
<service name="WcfEndpoints.Service1" behaviorConfiguration="WcfEndpoints.Service1Behavior">
<!-- Service Endpoints -->
<endpoint address="new" binding="wsHttpBinding" contract="WcfEndpoints.IService1" />
<endpoint address="old" binding="basicHttpBinding" contract="WcfEndpoints.IService1" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
Note you will need additional work for the basicHttpBinding endpoint to work with older (asmx) clients
http://msdn.microsoft.com/en-us/library/ms751433.aspx