This collection already contains an address with scheme Http - wcf

I want to have basic and Ws (over HTTP - Security is not a problem) and netTCP bindings at different urls.
<service name="WCFService.IHelloService" behaviorConfiguration="MyDefaultBehaviour">
<endpoint address="basicHttpAddress" binding="basicHttpBinding" contract="WCFService.IIHelloService"/>
<endpoint address="netTCPAddress" binding="netTcpBinding" contract="WCFService.IIHelloService"/>
<endpoint address="wsBindingAddress"
binding="wsHttpBinding" contract="WCFService.IIHelloService"
bindingConfiguration="wsBindingConfiguration"/>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
<host>
<baseAddresses>
<add baseAddress="http://localhost:8091/"/>
<add baseAddress="net.tcp://localhost:8095/"/>
<add baseAddress="http://localhost:8098/"/>
</baseAddresses>
</host>
Since I am having the multiple base address over the same protocol (http) I have also enabled multipleSiteBindingsEnabled .
But still I am having the same problem.
How to solve this?

Related

Configuring MEX and service in separate sections in web.config

I have basic question - can we assume that both configurations does the same thing?
web.config one
<service behaviorConfiguration="endpointBehavior" name="mYwebSrv.mYDevice">
<endpoint address="" binding="basicHttpBinding" contract="mYwebSrv.ImYDevice"></endpoint>
</service>
<service behaviorConfiguration="endpointBehavior" name="mYwebSrv.mYDevice">
<endpoint address="mex" binding="mexHttpBinding" bindingConfiguration="" contract="IMetadataExchange" />
</service>
web.config two
<service behaviorConfiguration="endpointBehavior" name="mYwebSrv.mYDevice">
<endpoint address="" binding="basicHttpBinding" contract="mYwebSrv.ImYDevice"></endpoint>
<endpoint address="mex" binding="mexHttpBinding" bindingConfiguration="" contract="IMetadataExchange" />
</service>
Not exactly.
Since you declared a new Service in your Web.config, it cannot have the same key for both services (endpointBehavior and name).
As you want to expose an endpoint to your service and an endpoint for the same service but for metadata (mex), it makes sense to put both under same service, that is as Microsoft recommends, see here: https://msdn.microsoft.com/en-us/library/ms734765.aspx
<service
name="Metadata.Example.SimpleService"
behaviorConfiguration="SimpleServiceBehavior">
<endpoint address=""
binding="wsHttpBinding"
contract="Metadata.Example.ISimpleService" />
<endpoint address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange" />
</service>
Hope it helps.

Can I use wsHttpBinding along with webHttpBinding in WCF service?

I have a custom username-password WCF service that needs to be called by Windows client (Winforms application) as well as by Web client (html/aspx page). I have two endpoints declarations in web.config but, to make it work, I have to comment one of them and so, only the client type, associated with that un-commented endpoint, can access the service. If I un-commment that, and comment the other one, other client can access it. I can't keep both of them and so I can't access it with both types of clients.
<service behaviorConfiguration="Behavior1" name="BeST.Service.Service">
<endpoint address="" binding="webHttpBinding" contract="BeST.Service.IService" behaviorConfiguration="EndpBehavior"></endpoint>
<endpoint address="" binding="wsHttpBinding" bindingConfiguration="Binding1"
contract="BeST.Service.IService" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost/" />
</baseAddresses>
</host>
</service>
just as the code shows, I need to use both endpoints (above two endpoints) if I want to make this service work for both clients OR, if there's another way to have it done, please help!
The problem is that you are giving the same address to both endpoints. Try to give another relative address to one of your endpoints and it should work.
<service behaviorConfiguration="Behavior1" name="BeST.Service.Service">
<endpoint address="web" binding="webHttpBinding" contract="BeST.Service.IService" behaviorConfiguration="EndpBehavior"></endpoint>
<endpoint address="" binding="wsHttpBinding" bindingConfiguration="Binding1"
contract="BeST.Service.IService" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost/" />
</baseAddresses>
</host>
</service>

How to start host & start service with two endpoint with WcfSvcHost.exe

i have one service with two endpoint. one endpoint is for wsdual binding and another for tcp binding. when i start my wcf service with wcfsvchost.exe like
WcfSvcHost.exe /service:"C:
\Users\TRIDIP\Documents\Visual Studio 2010\Projects\BBAChatService\BBAChatService\bin
\BBAChatService.dll" /config:"C:\Users\TRIDIP\documents\visual studio 2010\Projects
\BBAChatService\BBAChatService\Web.config"
then my service was started but it is showing only one mex endpoint. it should show two mex endpoint because i have two endpoint declared in web.config file. here is my config file entry.
<service name="BBAChatService.ChatService" behaviorConfiguration="BBAChatService.ChatServiceBehavior" >
<host>
<baseAddresses>
<add baseAddress ="http://localhost:8732/ChatService.svc/"/>
<add baseAddress ="net.tcp://localhost:7998/ChatService/"/>
</baseAddresses>
</host>
<endpoint name="dual_bind"
address="dual"
binding="wsDualHttpBinding"
bindingConfiguration="WSDualHttpBinding_IChatService"
contract="BBAChatService.IChatService">
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
<endpoint name="tcp_bind"
address="tcp"
binding="netTcpBinding"
bindingConfiguration="tcpBinding"
contract="BBAChatService.IChatService">
</endpoint>
<endpoint address="net.tcp://localhost:7996/ChatService/mex"
binding="mexTcpBinding"
contract="IMetadataExchange"/>
</service>
is there anything i miss in config file. please guide me what i need to do as a result wcfsvchost will show two different endpoint for my service. thanks

Is it possible to return different wsdls for different contracts on the same service?

I have a WCF service implementing two contracts on two different endpoints. I would like a client to be able to point at an endpoint (rather than the base address of the service) and get the wsdl just for the contract implemented on that endpoint (rather than a wsdl containing all contracts).
Is this possible? If so, how can it be achieved?
Instead of setting up the service like shown below (with a single SVC file if hosting in IIS)
<services>
<service name="YourOrg.YourService">
<endpoint address=""
binding="wsHttpBinding"
contract="YourOrg.IYourServiceThisContract" />
<endpoint address="That"
binding="wsHttpBinding"
contract="YourOrg.IYourServiceThatContract" />
<endpoint address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange"/>
</service>
</services>
Set each contract as a separate service class (with its own SVC file in the same IIS website)
<services>
<service name="YourOrg.ThisService">
<endpoint address=""
binding="wsHttpBinding"
contract="YourOrg.IYourServiceThisContract" />
<endpoint address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange"/>
</service>
<service name="YourOrg.ThatService">
<endpoint address=""
binding="wsHttpBinding"
contract="YourOrg.IYourServiceThatContract" />
<endpoint address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange"/>
</service>
</services>

Can several WCF services share a common BaseAddress?

I've got an assembly containing several WCF services, each with its own contract. It all works nicely. The service config in the app.config for the service looks like this:
<services>
<service behaviorConfiguration="WcfService.AlyzaServiceBehavior"
name="Sam.Alyza.WcfService.ServiceWebsites">
<endpoint address="" binding="netTcpBinding" contract="Sam.Alyza.WcfInterface.IServiceWebsites">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:8731/Design_Time_Addresses/SamAlyza/Websites/" />
</baseAddresses>
</host>
</service>
<service behaviorConfiguration="Sam.Alyza.WcfService.LogReaderServiceBehavior"
name="Sam.Alyza.WcfService.ServiceLogReader">
<endpoint address="" binding="netTcpBinding" contract="Sam.Alyza.WcfInterface.IServiceLogReader">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:8731/Design_Time_Addresses/SamAlyza/LogReader/" />
</baseAddresses>
</host>
</service>
<service behaviorConfiguration="Sam.Alyza.WcfService.ServiceSystemverwaltungBehavior"
name="Sam.Alyza.WcfService.ServiceSystemverwaltung">
<endpoint address="" binding="netTcpBinding" contract="Sam.Alyza.WcfInterface.IServiceSystemverwaltung">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:8731/Design_Time_Addresses/SamAlyza/Systemverwaltung/" />
</baseAddresses>
</host>
</service>
[...]
</services>
Since I've got a bigger project in mind, with more contracts, I'd like to have a way to share the BaseAddress between the different service contracts.
If this would just be one service with different contracts and endpoints, I could set a ommon baseaddress, but how do I set a common baseaddress for more than one service?
Of course I'd need something similar for the client.
You can combine all contracts in one class, so you have one service with a baseaddress and one (or more) endpoint(s) per contract.
To avoid having one large class-file you can use the partial-keyword (asuming you use c#) to split the class across multiple files. Each file can implement one contract, that makes maintaining the individual interfaces much easier.
In C++ you can use #includes or multiple inheritance, but that imply a large amount of discipline...
Your config would look like this:
<services>
<service behaviorConfiguration="WcfService.AlyzaServiceBehavior"
name="Sam.Alyza.WcfService.ServiceAll">
<endpoint address="Websites/" binding="netTcpBinding" contract="Sam.Alyza.WcfInterface.IServiceWebsites">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="LogReader/" binding="netTcpBinding" contract="Sam.Alyza.WcfInterface.IServiceLogReader">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="Systemverwaltung/" binding="netTcpBinding" contract="Sam.Alyza.WcfInterface.IServiceSystemverwaltung">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:8731/Design_Time_Addresses/SamAlyza/" />
</baseAddresses>
</host>
</service>
</services>
Services can share BaseAddress values (including port #'s, if the Net.Tcp Port Sharing Service is running). It's the endpoint addresses that must be unique. Notice in your config file that the MEX endpoints for each ServiceHost have an address of "mex". Your other endpoints have an address of empty string. When you provide a relative address for an endpoint to WCF (in the config file at least), the base address is prepended to it. Therefore, the MEX endpoint address for the LogReader service is "net.tcp://localhost:8731/Design_Time_Addresses/SamAlyza/LogReader/mex".
Since a relative address was not set on the main service endpoint, the base address of the ServiceHost is used as the actual address for the main service endpoint. Because no two endpoints can have overlapping Uri.AbsolutePath values, your example would lead you to believe that base address values cannot be shared. The ServiceHost class that hosts WCF services does not have a built-in endpoint, whereas the ServiceEndpoint class has a ListenUri property that will be populated based on the settings you provide.
If you change the baseAddress values in your example to all match, as long as you set unique relative address values on the Endpoint elements, everything should work. However, it appears that you may run into some challenges with the MEX endpoints, since they all have the address "mex" currently. Make those unique and you should be fine.
Now, I must ask, are you sure that you are not simply wanting these services to share a namespace, rather than base addresses?
You can also set the base addresses in code if you use a custom ServiceHostFactory.
In config you can have some app setting:
<configuration>
<appSettings>
<add key="BaseAddress" value="http://localhost:1234" />
</appSettings>
<configuration>
Then make a custom ServiceHostFactory:
public sealed class MyServiceHostFactory : ServiceHostFactory
{
protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
{
var baseAddy = ConfigurationManager.AppSettings["BaseAddress"];
baseAddresses.Add(new Uri(baseAddy));
return new ServiceHost(serviceType, baseAddresses);
}
}
Then you also have to change your .svc files to use that factory:
<%# ServiceHost Language="C#" Debug="true" Service="MyApp.MyService" CodeBehind="MyService.svc.cs" Factory="MyApp.MyServiceHostFactory" %>