Unable to view WCF Mex EndPoints output in Web Browser - wcf

I am new to WCF and trying to understand Mex endpoints. I have created a testservice. Its working fine and I am able to view WSDL output from URL= "http://myweb.com:8000/testservice" as well using "URL" or "URL?wsdl".
However, I am getting 400 Bad request while browsing "URL/mex" in browser. I set httpGetEnabled="false" and then I am also able generate proxy class using svcutil as well.
Could you please advise why I am not able to veiw mex endpoint output in web browser. Below is the config file:
App.Config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<services>
<service name="HelloTest.testservice" behaviorConfiguration="serviceBehaviour">
<endpoint binding="basicHttpBinding" contract="HelloTest.Itestservice" address="HelloTest">
</endpoint>
<endpoint binding="mexHttpBinding" contract="IMetadataExchange" address="mex">
</endpoint>
<host>
<baseAddresses>
<add baseAddress="http://myweb.com:8000/testservice"/>
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="serviceBehaviour">
<serviceMetadata httpGetEnabled="true"></serviceMetadata>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>

Related

WCF IMetadataExchange Error

I have created a service host with following configuration.
<?xml version="1.0"?>
<configuration>
<system.serviceModel>
<services>
<service name="MathServiceLib.MathService" behaviorConfiguration="myMathServiceBehave">
<host>
<baseAddresses>
<add baseAddress="http://localhost:9001/MathService"/>
<add baseAddress="net.tcp://localhost:9002/MathService"/>
</baseAddresses>
</host>
<endpoint address="http://localhost:9001/MathService" binding="basicHttpBinding" contract="MathServiceLib.IMathService"/>
<endpoint address ="net.tcp://localhost:9002/MathService" binding ="netTcpBinding" contract="MathServiceLib.IMathService"/>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
<!--<endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange"/>-->
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="myMathServiceBehave">
<!--<serviceMetadata httpGetEnabled="true"/>-->
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
I don't want to use serviceMetadata httpGetEnabled="true" property instead I want to use MEX binding for proxy creation.
Now when I start my service using
svcHost = new ServiceHost(typeof(MathServiceLib.MathService));
svcHost.Open();
I get following error, please help.
The contract name 'IMetadataExchange' could not be found in the list of contracts implemented by the service MathService. Add a ServiceMetadataBehavior to the configuration file or to the ServiceHost directly to enable support for this contract.
Based on my experience, you need to specify
<serviceMetadata httpGetEnabled="true"/>
if you want to use
<endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange"/>
The following articles provide comprehensive information and examples:
http://msdn.microsoft.com/en-us/library/ms734765(v=vs.110).aspx
http://www.c-sharpcorner.com/UploadFile/81a718/wcf-service-faqs-part-2/

Add service reference when using netTcp binding

I have a WCF service that I tested by copying its interfaces to a sample client project.
Now I want to work properly by adding a service reference.
The service is hosted in windows hosting (using installUtil).
The service has 2 projects - externals (interfaces + datacontracts) and internals (implementations).
For some reason it didn't have an app.config so I added one manually:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<services>
<service name="ExecutionService" behaviorConfiguration="Default">
<endpoint name="TCPEndpoint" address="" binding ="netTcpBinding" contract="Externals.IExecutionService"/>
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:3040/ExecutionService"/>
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="Default">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
Trying to add a service reference from my sample client causes the following error:
Metadata contains a reference that cannot be resolved: 'net.tcp://localhost:3040/ExecutionService/Externals.IExecutionService'.
There was no endpoint listening at net.tcp://localhost:3040/ExecutionService/Externals.IExecutionService that could accept the message. This is often caused by an incorrect address or SOAP action. See InnerException, if present, for more details.
If the service is defined in the current solution, try building the solution and adding the service reference again.
I saw here that there's no need in app.config.
I'm a bit confused and I'm a beginner with WCF.
How can a nice WPF app reference my service? I want the service to be windows hosted and I don't want to drag dlls with me.
Edit
I added a metadata endpoint and my appconfig now looks like this:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<services>
<service name="ExecutionService" behaviorConfiguration="Default">
<endpoint name="TCPEndpoint"
address=""
binding ="netTcpBinding"
contract="Externals.IExecutionService"/>
<endpoint address="mex"
binding="maxHttpBinding"
contract="Externals.IExecutionService"/>
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:3040/ExecutionService"/>
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="Default">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
I tried adding a service reference by using net.tcp://localhost:3040/ExecutionService, net.tcp://localhost:3040/ExecutionService/Externals and net.tcp://localhost:3040/ExecutionService/Externals/IExecutionService and I'm still getting the same error.
You need to do:
maxHttpBinding -> mexTcpBinding - you cannot use mexHttpBinding on net.tcp endpoint (and it's mex not max)
the contract for mex endpoint must be IMetadataExchange - as you want to have service metadata available through this endpoint
httpGetEnabled="false" as there will be no http endpoint to get metadata from
When I was testing the solution in a simple console host I needed to change name in <service> tag to Externals.ExecutionService (but this depends on how you instantiate the service)
Then your service reference will be available at: net.tcp://localhost:3040/ExecutionService/mex
as base address is net.tcp://localhost:3040/ExecutionService and the relative address for the mex endpoint is set to mex
Final app.config is below:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<services>
<service name="Externals.ExecutionService" behaviorConfiguration="Default">
<endpoint name="TCPEndpoint"
address=""
binding ="netTcpBinding"
contract="Externals.IExecutionService"/>
<endpoint address="mex"
binding="mexTcpBinding"
contract="IMetadataExchange"/>
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:3040/ExecutionService"/>
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="Default">
<serviceMetadata httpGetEnabled="false" />
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
For a quick test if the configuration is correct I used console host app as a service host.
Program.cs:
using System;
using System.ServiceModel;
namespace Externals
{
class Program
{
static void Main(string[] args)
{
var sh=new ServiceHost(typeof(ExecutionService));
sh.Open();
Console.WriteLine("Service running press any key to terminate...");
Console.ReadKey();
sh.Close();
}
}
}
Run the console app and try to add service reference to your project through net.tcp://localhost:3040/ExecutionService/mex.
At first glance, you've forgotten Metadata Endpoint
Change this:
<endpoint address="mex"
binding="maxHttpBinding"
contract="Externals.IExecutionService"/>
To:
<endpoint address="mex"
binding="mexTcpBinding"
contract="IMetadataExchange"/>
Notice it's not maxHttpBinding but mexTcpBinding, you had typo as well there.

Hosting WCF service

I am following THIS link to create my wcf service and hosting through window service its is working fine but when i change my namespace from "Microsoft.ServiceModel.Samples" to "EE.ServiceProcess.ABC" and do changes accordingly in app.config my window service dont get start properly
my
App.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<services>
<service name="EE.ServiceProcess.ABC.CalculatorService"
behaviorConfiguration="CalculatorServiceBehavior">
<host>
<baseAddresses>
<add baseAddress="http://localhost:8000/EEServiceProcessABCservice/service"/>
</baseAddresses>
</host>
<!-- this endpoint is exposed at the base address provided by host: http://localhost:8000/EEServiceProcessABCservice/service -->
<endpoint address=""
binding="wsHttpBinding"
contract=" EE.ServiceProcess.ABC.ICalculator" />
<!-- the mex endpoint is explosed at http://localhost:8000/EEServiceProcessABCservice/service/mex -->
<endpoint address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="CalculatorServiceBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="False"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
Can any one please suggest where am i going wrong?

WCF error : A registration already exists for URI

Below is my WCF service configuration. I use 2 ServiceHost to host 2 service types. They use the same base address, but they use different relative addresses for their endpoints.
But I got this error, why?
Service cannot be started. System.InvalidOperationException: The ChannelDispatcher at 'http://earth:1111/' with contract(s) '"IHttpGetHelpPageAndMetadataContract"' is unable to open its IChannelListener. ---> System.InvalidOperationException: A registration already exists for URI 'http://earth:1111/'.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="serviceBehavior">
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="serviceBehavior" name="Distributed.Troubleshooting.System.IIS.IISServiceType">
<endpoint address="iis" binding="basicHttpBinding" name="iis"
contract="Distributed.Troubleshooting.System.IIS.IISServiceContract" />
<endpoint address="iismex" binding="mexHttpBinding" bindingConfiguration=""
name="iismex" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://Earth:1111/" />
</baseAddresses>
</host>
</service>
<service behaviorConfiguration="serviceBehavior" name="Distributed.Troubleshooting.System.SQL.SQLServiceType">
<endpoint address="sql" binding="basicHttpBinding" name="sql"
contract="Distributed.Troubleshooting.System.SQL.SQLServiceContract" />
<endpoint address="sqlmex" binding="mexHttpBinding" bindingConfiguration=""
name="sqlmex" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://Earth:1111/" />
</baseAddresses>
</host>
</service>
</services>
</system.serviceModel>
</configuration>
Some even more ridiculous findings:
I changed my configuration to this:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="serviceBehavior">
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="serviceBehavior" name="Distributed.Troubleshooting.System.IIS.IISServiceType">
<endpoint address="http://Earth:1111/iis" binding="basicHttpBinding" name="iis"
contract="Distributed.Troubleshooting.System.IIS.IISServiceContract" />
<endpoint address="http://Earth:1111/iismex" binding="mexHttpBinding" bindingConfiguration=""
name="iismex" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://Earth:1111/iis" />
</baseAddresses>
</host>
</service>
<service behaviorConfiguration="serviceBehavior" name="Distributed.Troubleshooting.System.SQL.SQLServiceType">
<endpoint address="http://Earth:1111/sql" binding="basicHttpBinding" name="sql"
contract="Distributed.Troubleshooting.System.SQL.SQLServiceContract" />
<endpoint address="http://Earth:1111/sqlmex" binding="mexHttpBinding" bindingConfiguration=""
name="sqlmex" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://Earth:1111/sql" />
</baseAddresses>
</host>
</service>
</services>
</system.serviceModel>
</configuration>
Then I found I can use "Add Service Reference" in Visual Studio with the following addresses:
http://Earth:1111/iis
http://Earth:1111/iismex
http://Earth:1111/sql
http://Earth:1111/sqlmex
It is possible to host more than one Service with the same base address. Set the HttpHelpPageEnabled and the HttpsHelpPageEnabled properties of all ServiceDebugBehaviors to false, then it should work.
Atention: By default, there's always a ServiceDebugBehavior registered in the behavior's description collection of a host even if it is not specified explicitely (I tried it only with programatic configration and the ServiceHost class, not via XML config). So, you should add an explicit ServiceDebugBehavior and set the mentioned properties. The IncludeExceptionDetailInFaults property can be true.
Have you tried removing one of the Service blocks and combining the endpoints into one?
I cant see any reason why you have them seperated.
Make sure the baseaddress + endpoint address are unique.
You can't host two services with the same base address.
You need to host the other one on a different port or address.
Something like
http://Earth:1111/Service1
and
http://Earth:1111/Service2
I don't really know why this is the case but one solution is to leave the service with no base address and to specify the full address for the endpoints. This doesn't change the address of the different endpoints, nor the addresses unicity. I could not find any relevant reference for this on MSDN.
From my own experience, the problem appears with http and not with net.tcp. I am not using service metadata. I thought the "IHttpGetHelpPageAndMetadataContract" has to do with metadata but found no way to disable it.
You'll also get this error if you accidentally start the same service twice rather than start the two different services.

mexTcpBinding in WCF - IMetadataExchange errors

I'm wanting to get a WCF-over-TCP service working. I was having some problems with modifying my own project, so I thought I'd start with the "base" WCF template included in VS2008.
Here is the initial WCF App.config and when I run the service the WCF Test Client can work with it fine:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.web>
<compilation debug="true" />
</system.web>
<system.serviceModel>
<services>
<service name="WcfTcpTest.Service1" behaviorConfiguration="WcfTcpTest.Service1Behavior">
<host>
<baseAddresses>
<add baseAddress="http://localhost:8731/Design_Time_Addresses/WcfTcpTest/Service1/" />
</baseAddresses>
</host>
<endpoint address="" binding="wsHttpBinding" contract="WcfTcpTest.IService1">
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="WcfTcpTest.Service1Behavior">
<serviceMetadata httpGetEnabled="True"/>
<serviceDebug includeExceptionDetailInFaults="True" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
This works perfectly, no issues at all.
I figured changing it from HTTP to TCP would be trivial: change the bindings to their TCP equivalents and remove the httpGetEnabled serviceMetadata element:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.web>
<compilation debug="true" />
</system.web>
<system.serviceModel>
<services>
<service name="WcfTcpTest.Service1" behaviorConfiguration="WcfTcpTest.Service1Behavior">
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:1337/Service1/" />
</baseAddresses>
</host>
<endpoint address="" binding="netTcpBinding" contract="WcfTcpTest.IService1">
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="WcfTcpTest.Service1Behavior">
<serviceDebug includeExceptionDetailInFaults="True" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
But when I run this I get this error in the WCF Service Host:
System.InvalidOperationException: The contract name 'IMetadataExchange' could not be found in the list of contracts implemented by the service Service1. Add a ServiceMetadataBehavior to the configuration file or to the ServiceHost directly to enable support for this contract.
I get the feeling that you can't send metadata using TCP, but that's the case why is there a mexTcpBinding option?
Well, if you want to have metadata - TCP or HTTP - you still need to include the serviceMetadata behavior!
<behaviors>
<serviceBehaviors>
<behavior name="WcfTcpTest.Service1Behavior">
<serviceDebug includeExceptionDetailInFaults="True" />
<serviceMetadata />
</behavior>
</serviceBehaviors>
</behaviors>
Sure, you can't have a "HttpGetEnabled" on it - but the behavior itself must be present in order to enable exchange of metadata (and thus the IMetadataExchange contract).