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
Related
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?
I have 3 service contract interfaces in my WCF library like this:
public interface ServiceContract1{}
public interface ServiceContract2{}
public interface ServiceContract3 : ServiceContract1, ServiceContract2 {}
Also I have a service which implements ServiceContract3. I can have different endpoints by setting different contracts for each like this:
<endpoint address="net.tcp://localhost:5556/ServiceContract1"
binding="netTcpBinding" name="netTcpBinding1"
contract="WcfServiceLibrary.IServiceContract1">
<endpoint address="net.tcp://localhost:5556/ServiceContract2"
binding="netTcpBinding" name="netTcpBinding2"
contract="WcfServiceLibrary.IServiceContract2">
These endpoints seem to work very well but there is only one mexHttpBinding endpoint automatically generated. Thus, although a client needs to use one of the endpoints, it will have whole classes after adding Service Reference.
Can i have different mexHttpBinding endpoints for different contracts? Is there any approach can i follow? Thanks for your help.
Edit #1: ServiceModel configuration
<system.serviceModel>
<services>
<service name="WcfServiceLibrary.Service">
<endpoint address="net.tcp://localhost:5556/Service1"
binding="netTcpBinding" name="netTcpBinding"
contract="WcfServiceLibrary.IServiceContract1">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="net.tcp://localhost:5556/Service2"
binding="netTcpBinding" name="netTcpBinding"
contract="WcfServiceLibrary.IServiceContract2">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding"
name="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:5555/ConsoleHost" />
</baseAddresses>
</host>
</service>
</services>
</system.serviceModel>
I have only one service hosted in my console application:
ServiceHost host = new ServiceHost(typeof(WcfServiceLibrary.Service));
host.Faulted += new EventHandler(Host_Faulted);
// Start listening for messages
host.Open();
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>
I have created a WCF service in which i have one service contract and multiple services classes implementing the same contract.
Could you please tell me what to edit in the app.config and how to host this service in console app.
I have one service contract and i implemented this contract in three *.cs files in wcf.
Thanks.
here is the App.config that i have written
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.web>
<compilation debug="true" />
</system.web>
<!-- When deploying the service library project, the content of the config file must be added to the host's
app.config file. System.Configuration does not support config files for libraries. -->
<system.serviceModel>
<services>
<service name="ProductService.Service1">
<host>
<baseAddresses>
<add baseAddress = "http://localhost:8732/Design_Time_Addresses/ProductService/Service1/" />
</baseAddresses>
</host>
<!-- Service Endpoints -->
<!-- Unless fully qualified, address is relative to base address supplied above -->
<endpoint address ="" binding="wsHttpBinding" contract="ProductService.IService1">
<!--
Upon deployment, the following identity element should be removed or replaced to reflect the
identity under which the deployed service runs. If removed, WCF will infer an appropriate identity
automatically.
-->
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<!-- Metadata Endpoints -->
<!-- The Metadata Exchange endpoint is used by the service to describe itself to clients. -->
<!-- This endpoint does not use a secure binding and should be secured or removed before deployment -->
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
<service name="ProductService.RegistrationService">
<host>
<baseAddresses>
<add baseAddress="http://localhost:7777/Design_Time_Addresses/ProductService/RegistrationService/"/>
</baseAddresses>
</host>
<endpoint address="" binding="wsHttpBinding" contract="ProductService.IService1">
<identity>
<dns value ="localhost"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
<service name="ProductService.ProductService">
<host>
<baseAddresses>
<add baseAddress="http://localhost:8888/Design_Time_Addresses/ProductService/ProductService/"/>
</baseAddresses>
</host>
<endpoint address="" binding="wsHttpBinding" contract="ProductService.IService1">
<identity>
<dns value ="localhost"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
<service name="ProductService.CatogeryService">
<host>
<baseAddresses>
<add baseAddress="http://localhost:8080/Design_Time_Addresses/ProductService/CatogeryService/"/>
</baseAddresses>
</host>
<endpoint address="" binding="wsHttpBinding" contract="ProductService.IService1">
<identity>
<dns value ="localhost"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information,
set the value below to false and remove the metadata endpoint above before deployment -->
<serviceMetadata httpGetEnabled="True"/>
<!-- To receive exception details in faults for debugging purposes,
set the value below to true. Set to false before deployment
to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="False" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
I imagine you have defined several service operations on the service contract? What you are trying to do is not possible, nor is it desirable.
Because a logical service is associated with exactly one service contract, you cannot add more than one service for the same contract.
You can add multiple service endpoints per service contract, but not on a per operation basis. You may want to do this to offer your service across two or more different transports, for example, HTTP and HTTPS.
You can consume all the operations from a single service (you have 4 services defined, so just get rid of the last three), but I don't think that is what you want to do.
To host each service operation on a separate service endpoint, you will needs to break up your service contract into multiple contracts.
This is more desirable as it reduces coupling between your endpoints and makes it much easier to understand what is going on.
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" %>