WCF TCP Shared Services Enable Service Fails to Start - c#

In short, when I go to start the worker process service process, it fails and returns:
The CS.Connector.Protean service on Local Computer started and then
stopped. Some services stop automatically if they are not in use by
other services or programs
I remove the attribute portSharingEnabled="true" from the service model in the config file and then the worker process service starts and executes as expected. I then add the attribute back into the config and the worker process services won't start again. I have include the service model config at the bottom of this post.
The Net.TCP Sharing Service is running, so it should be intercepting the incoming net.TCP connection.
I have read this MSDN article, but I must be missing something somewhere.
Could it be do doe with the mex end point not using a port sharing binding? I tried adding a binding to the mex end point, but still no joy. :.(
Help! Thanks
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="TCPSecure" portSharingEnabled="true">
<security mode="Message" />
</binding>
</netTcpBinding>
</bindings>
<services>
<service name="Protean.Connector.ProteanConnector">
<endpoint address="" binding="netTcpBinding" bindingConfiguration="TCPSecure" contract="Protean.Connector.IProteanConnector"></endpoint>
<endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="net.tcp://10.1.2.124:60000/ProteanConnector" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpGetEnabled="false" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
Update!
I started off with a working service and confirmed this by a test.
I added the attribute port sharing and the service failed to start.
I removed the mex end point and the service ran successfully. An application that had a established connection was able to use the service successfully.
I added the mex back in with a reference to a binding that only had port sharing enabled and the service fail to start.
I need the mex to make the service discoverable to the IDE Visual Studios.
I suppose that the question now is, how does the end point, for the metadata exchange, work along with the port sharing attribute?
Update 2
MSDN Social Webpage Link
This forum tells me to change the mex binding from mexTcpBinding to netTcpBinging. I did and the service ran, but I am unable to discover the service now in the IDE.
Is this the correct solution path? The journey continues.
I'm starting to think the deeper I dig the more likely it will be that I stumble upon some government conspiracy. #HumourInDarkTimes #StrangerThings ;)

Solution
var type = typeof(LoggingManager);
using (var host = new ServiceHost(type))
{
/*
* Work-around to the conflict between global port sharing and local port sharing
* caused by Net.Tcp Sharing Serivces and the default port exclusivity (hogging) of Metadata Exchange binding.
*/
var mexBinding = new CustomBinding(MetadataExchangeBindings.CreateMexTcpBinding());
mexBinding.Elements.Find<TcpTransportBindingElement>().PortSharingEnabled = true;
host.AddServiceEndpoint(typeof(IMetadataExchange), mexBinding, "mex");
host.Open();
Console.WriteLine("Service started. Press [Enter] to exit.");
Console.ReadLine();
host.Close();
}
Description of Solution
I read a number of articles that suggests a solution through swapping the binding mexTcpBinding for netTCPBinding, I found that this did not work in my instance.
The above solution gets the mexTCPBinding and adds to it the attribute PortSharingEnabled = true. This is used in creating a new endpoint code-matically and passed to the service host. Finally, I have removed the meta-exchange end point from the config and, hey-presto, it worked.
Useful Links
Article explaining fix
Similar question

Related

add service reference only works with localhost wcf service

I am trying to host a svc service in my web application and I am trying to connect to it with a simple client application.
When the host is hosted in my own computer and solution, and I run the web application locally, everything works fine, meaning that I can add the reference to the service using add service reference in my client solution with http://localhost:6543/Hello.svc as the address and when I navigate to the service's url, it shows me the service's information as it should.
But when I publish my website, and I try to add the reference to my service using add service reference with http://myserver.com/Hello.svc as the address, i get the error message bleow:
There was an error downloading
'http://myserver.com/Hello.svc/_vti_bin/ListData.svc/$metadata'. The
request failed with HTTP status 404: Not Found. Metadata contains a
reference that cannot be resolved: 'http://myserverc.com/Hello.svc'.
The remote server returned an unexpected response: (405) Method Not
Allowed. The remote server returned an error: (405) Method Not
Allowed. If the service is defined in the current solution, try
building the solution and adding the service reference again.
and oddly when I navigate to myserver.com/Hello.svc, the browser starts to download the Hello.svc file instead of showing the service's details and information.
this is my website's web.config file:
<system.serviceModel>
<bindings>
<webHttpBinding>
<binding name="crossDomain" crossDomainScriptAccessEnabled="true" />
</webHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="WithDebug">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
<services>
<service name="HelloWorldService.HelloService" behaviorConfiguration="WithDebug">
<host>
<baseAddresses>
<add baseAddress="http://myserver/Hello.svc"/>
</baseAddresses>
</host>
<endpoint
address=""
binding="webHttpBinding" bindingConfiguration="crossDomain"
contract="HelloWorldService.IHelloWorld" />
<endpoint
address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange" />
</service>
</services>
</system.serviceModel>
I think I am missing something big here, but since I am new to WCF, I don't know what it is.Any help would be appreciated and I am more than happy to issue more details about my project if needed.
Thanks in advance
You need to run ServiceModel registration tool
"This command-line tool provides the ability to manage the registration of WCF and WF components on a single machine. Under normal circumstances you should not need to use this tool as WCF and WF components are configured when installed. But if you are experiencing problems with service activation, you can try to register the components using this tool."

WCF Service Unable to start debugging on the web server

I am having an issue debugging my WCF service when I set the WCF service to SSL Required in my local IIS. I am able to hit the URL correctly for my service under http/https but I cannot debug and step through the code. I received a popup box with the following text:
Unable to start debugging on the web server. The web server is not configured correctly.
When I make the service not SSL Required I am able to step through my code as expected. I am new to dealing with IIS and have gone through a number of tutorials with the same result. Any help would be awesome
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="sslBehaviorConfiguration">
<!-- To avoid disclosing metadata information, set the values below to false before deployment -->
<serviceMetadata httpsGetEnabled="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<wsHttpBinding>
<binding name="sslBindingConfiguration">
<security mode="Transport" />
</binding>
</wsHttpBinding>
</bindings>
<services>
<service name="SslWCFProject.Service1" behaviorConfiguration="sslBehaviorConfiguration">
<endpoint binding="wsHttpBinding" bindingConfiguration="sslBindingConfiguration" contract="SslWCFProject.IService1" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
<!--<protocolMapping>
<add binding="wsHttpBinding" scheme="https"/>
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"/>-->
1) First, I recommend checking the IIS logs. They are usually located in the following directory: C:\inetpub\logs\LogFiles. Just go into the W3SVC prefixed folder whose modification date most closely matches when you received the error. Open the log for the correct day and see the error details.
2) If that reveals nothing, then check out the Windows Application log in your Event Viewer.
3) Do you have a certificate (e.g. self signing certificate) on your computer? Is there a trusted site issue here?
I believe I found my answer. It looks like the checkbox in IIS for the website for Require SSL is associated the client certificate and requiring a client certificate to access the service instead of the section which is below it (although I will need to select required in the future). For the post I found When this is checked off I cannot debug the service but I can attach to the process in order to debug it.
http://blogs.msdn.com/b/vijaysk/archive/2007/10/18/visual-studio-debugging-websites-that-require-client-certificates.aspx
If I am wrong please let me know. If I come across anything else I'll update this question again with my progress just to keep in documented.

Minimum configuration to make "Add Service Reference > Discover" work

I have already a few WCF + Windows Service tested and working correctly as run as a Windows Service on remote dev machines. Except for one.
In order to debug, I tried to host the WCF (without the Windows Service) using the built-in "Add Service Reference" and then hosting it in visual studio (don't know what the host is called).
Anyways, I cannot get the Add Service Reference to Discover my services.
Since I am using Windoes Services, I am using TCP stuff. This are some things I have done, all in the winforms app that I am adding the service reference:
Add Project > Properties > Debug > Command line arguments: /client:"WcfTestClient.exe" but the exe doesn't run.
And my App.Config
<?xml version="1.0"?>
<configuration>
<system.serviceModel>
<client>
<endpoint address="net.tcp://localhost:32279/SYNC" binding="netTcpBinding"
bindingConfiguration="tcpSyncBindingConfig" contract="Company.Data.Sync.ILocalCacheSyncContract"
name="tcpSyncClientEP" />
</client>
<bindings>
<netTcpBinding>
<binding name="tcpSyncBindingConfig" maxReceivedMessageSize="6553600" />
</netTcpBinding>
<mexTcpBinding>
<binding name="tcpMexBindingConfig" />
</mexTcpBinding>
</bindings>
<services>
<service behaviorConfiguration="svcBehavior" name="Company.Data.Sync.Services.LocalCacheSyncService">
<endpoint address="net.tcp://localhost:32279/Sync" binding="netTcpBinding"
bindingConfiguration="tcpSyncBindingConfig" name="tcpSyncListenEP"
contract="Company.Data.Sync.Services.ILocalCacheSyncContract" />
<endpoint address="net.tcp://localhost:32279/Sync/mex" binding="mexTcpBinding"
bindingConfiguration="tcpMexBindingConfig" name="tcpMexEP" contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="svcBehavior">
<serviceMetadata httpGetEnabled="false" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
Side note: the ServiceOperation are returning Microsoft.Synchronization.Data.xxx sutff for example SyncContext. I might have to add a reference in the Winforms? Or will the "Add Service Reference" add them for me? The service and contracts are generated by the Local Database Cache template. perhaps not related to the problem.
After posting, I continued to look for answers and this is what I experimented to be working:
The project file itself e.g. *.csproj for C# project must contain the ProjectTypeGuid for WCF for Visual Studio to even start checking the project for Services.
<ProjectTypeGuids>{3D9AD99F-2412-4246-B90B-4EAA41C64699};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
More GUIDs can be found at http://www.mztools.com/articles/2008/mz2008017.aspx. (Thanks mztools!)
The WCF project can have multiple services, and each of them needs to to have their config defined in the project's App.Config. Each service needs to have a different mex endpoint address. The services can also share a single servicebehavior which has the serviceMetadata extension defined. Mex endpoint does not need behaviors or binding config. But remember to set mex endpoint contract to IMetadataExhchange.
For TCP mex, the serviceMetadata > HttpGetEnabled must be set to false.
I believe this is the minimum settings.
Right click on the service you wish to host on your PC, then right click and go Debug > Start New Instance
Then go your other application (I assume same solution) and copy the URL it is running at.
Then you can start that one with the same method above and debug both projects on your local machine.
I assume this is what you are trying to do. Please let me know if it was something else.

WCF - Service Reference not be created

My WCF service was working correctly and then all of sudden it stop working. I don't think I changed anything with the configuration.
The WCF service is hosted by a windows service.
What is weird is when I add the service reference, it will identify the contract and all the methods exposed. But if I go to a browser I get a 404 error and the compiler is not creating the service. I have deleted and tried to re-add the reference with no luck
Also, my deployed application is still able to access the wcf service.
Question 1:
In a WCF windows service, should I be able to see the wsdl inside a browser (http://localhost:8080/MaestroService/mex). In IE, I am getting 400 Bad Request. I am assuming that this is the root of the problem.
Question 2:
Is there something else?
App.config
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="NewBinding0" />
</basicHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="metadataAndDebug">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug httpHelpPageEnabled="true" includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="metadataAndDebug" name="MaestroServiceLibrary.MaestroService">
<endpoint address="basic" binding="basicHttpBinding" bindingConfiguration="NewBinding0"
name="basicHttp" contract="MaestroServiceLibrary.IMaestroService" />
<endpoint address="mex" binding="mexHttpBinding" bindingConfiguration=""
contract="IMetadataExchange" />
<endpoint address="net.tcp://localhost:8888/MaestroService" binding="netTcpBinding"
bindingConfiguration="" name="netTcpBinding" contract="MaestroServiceLibrary.IMaestroService" />
<endpoint address="net.pipe://localhost/MaestroService" binding="netNamedPipeBinding"
bindingConfiguration="" name="netNamedPipeBinding" contract="MaestroServiceLibrary.IMaestroService" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8080/MaestroService" />
</baseAddresses>
</host>
</service>
</services>
Errors Compiling:
Custom tool error: Failed to generate code for the service reference 'MaestroService'. Please check other error and warning messages for details.
Custom tool warning: Cannot import wsdl:binding
Detail: There was an error importing a wsdl:portType that the wsdl:binding is dependent on.
XPath to wsdl:portType: //wsdl:definitions[#targetNamespace='http://tempuri.org/']/wsdl:portType[#name='IMaestroService']
XPath to Error Source: //wsdl:definitions[#targetNamespace='http://tempuri.org/']/wsdl:binding[#name='basicHttp']
Update
I turned on the tracing and I saw this:
The message with To 'http://localhost:8080/MaestroService/mex/mex' cannot be processed at the receiver, due to an AddressFilter mismatch at the EndpointDispatcher. Check that the sender and receiver's EndpointAddresses agree. I will update this question if I figure it out.
Update V2
I went to another project inside the same solution. I was able to add the service there with no problems. I notice I was using 3.5 in the console app vs 4.0 in the wpf browser app. When I came back to report this, I noticed in my last update that it had /mex/mex even though I put http://localhost:8080/MaestroService/mex in the url . I tried just http://localhost:8080/MaestroService and it work!!!
In the end, I did end up using Migual Castro technique here, where you create the conracts and the proxy. Which was good to see how it really works and what VS is doing. But it would be good to have that day and a half back.
thanks for the suggestions everyone.
You are running as a windows service.
A windows service runs in the security context of a user account.
If the password of the user account changes or expires, the service does not run.
The first thing that you should check is: Is the service running.

WCF and Multiple Host Headers

My employers website has multiple hostnames that all hit the same server and we just show different skins for branding purposes.
Unfortunately WCF doesn't seem to work well in this situation.
I've tried overriding the default host with a custom host factory.
That's not an acceptable solution because it needs to work from all hosts, not just 1.
I've also looked at this blog post but either I couldn't get it to work or it wasn't meant to solve my problem.
The error I'm getting is "This collection already contains an address with scheme http"
There's got to be a way to configure this, please help :)
If you don't put an address in the endpoint then it should resolve to whatever server hits the service. I use this code and it resolves both to my .local address and to my .com address from IIS.
<system.serviceModel>
<services>
<service name="ServiceName" behaviorConfiguration="ServiceName.Service1Behavior">
<endpoint address="" binding="wsHttpBinding" contract="iServiceName">
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceName.Service1Behavior">
<!-- 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="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
I don't think that the host base addresses solution posted above will work for IIS-hosted websites (the OP did mention that this was for his employer's website).
See this blog post
Also, the other answer further up by thaBadDawg won't work where multiple host headers are specified - you'll just get the errors that the OP mentions ("This collection already contains an address with scheme http".)
I don't think any of the solutions mentioned so far will work, because it doesn't look like WCF allows a single service to be accessible for a single site with multiple host headers from all of the sites. The only workaround I could find for .Net 3.5 (and under) is to create a different contract for each of the host headers, and use the custom ServiceHostFactory to use the correct host header based on which contract is specified. This isn't at all practical. Apparently .Net 4.0 will resolve this issue.
I met this problem several days ago. Actually I have the same situation that Ryu described originally in his question. We have one virtual directory for many customers but each of them has his own binding. Like "http://company1.product.com", "http://company2.product.com" etc.
Solution described here works. But what is the price! We should change web.config each time when we need to add new binding. And also web.config should contain absolute path prefix
like <add prefix=”http://company1.product.com”/>.
It is possible to bypass first problem. I wrote my own CustomHostFactory for WCF service, where I dynamically add endpoints. And this endpoints I retrieve from IIS bindings(there is a way to get information from IIS).
Here is sample code :
protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
{
var serviceHost = base.CreateServiceHost(serviceType, baseAddresses);
var webHttpBinding = new WebHttpBinding();
var serviceEndpoint1 = serviceHost.AddServiceEndpoint(typeof(IService), webHttpBinding,
"http://company2.product.com/WCFService/Service.svc");
var serviceEndpoint2 = serviceHost.AddServiceEndpoint(typeof(IService), webHttpBinding,
"http://company1.product.com/WCFService/Service.svc");
var webHttpBehavior = new WebHttpBehavior();
serviceEndpoint1.Behaviors.Add(webHttpBehavior);
serviceEndpoint2.Behaviors.Add(webHttpBehavior);
return serviceHost;
}
And instead of hardcoding endpoint urls, you sould retrieve them from IIS.
But ServiceHost is created once when application starts. So if you need to add new binding, you should restart IIS. It is not a solution for us.
That is why we decided to move to asmx (like is described here).
And wait until Framework 4.0 release, where multiple bindings should be supported.
A simple workaround that doesn't involve any code or config changes is to create yet another website in IIS which points to the same physical directory, and the same app pool, but with a different host-header binding. This can be done for as many different host names as you have.
I'm sure you've figured it out by now, but just for fun I'll post here anyway.
I've had this exact problem and spent forever trying to figure it out. The best solution is to put the host base addresses in your service definition, which allows the service to operate under these multiple addresses. For this solution to work, you still need the ServiceHostFactory to be overridden. Since you've already done that, just leave it in there.
<service behaviorConfiguration="ServiceBehaviour" name="Api.Service">
<endpoint address="soap" binding="basicHttpBinding" contract="Api.IService" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://host1.com/Api" />
<add baseAddress="http://host2.com/Api" />
</baseAddresses>
</host>
</service>

Categories

Resources