I want to expose 2 endpoints on my WCF service. First offers standard methods for users over HTTP, second one offers "administrator-only" method ovet net.tcp.
I have only 1 class, that implements both ServiceContracts exposed by endpoints, like that:
public class ComputingModuleProvider : IComputingModuleProvider, IComputingModuleAdminProvider
My App.Config looks like this:
<services>
<service behaviorConfiguration="ComputingModuleBehaviour" name="ComputingModuleProvider.ComputingModuleProvider">
<endpoint address="ComputingModuleProvider" binding="basicHttpBinding" contract="ComputingModuleProvider.IComputingModuleProvider" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<endpoint address="ComputingModuleAdminProvider" binding="netTcpBinding" contract="ComputingModuleProvider.IComputingModuleAdminProvider" />
<endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8091/ComputingModuleProvider"/>
<add baseAddress="net.tcp://localhost:8092/ComputingModuleProvider" />
</baseAddresses>
</host>
</service>
</services>
Now the situation is that I have the service on the server-computer in our office and the client is on my personal computer (but both of them are connected to local network).
Still, I had to add an exception to server firewall and allow communication on ports 8091 and 8092 in order to be able to add service reference and generate proxy on client side. With this exception allowed, I can add service reference using both net.tcp and http base adress.
The problem is, that I see both ServiceContracs for each base adress, like in the image below:
I expected, that for net.tcp I would only see IComputingModuleAdminProvider and for http, I would see IComputingModuleProvider.
I also tried to exclude port 8092 from allowed ports on server firewall - that resulted in being able to add service reference only by using http base adress, but still, I could see both Service contracts exposed, like in image above.
So the administrator-only method is available over http as well.
Question:
Am I doing something wrong in my app.config file or is this the standard behaviour? I know I am on the same local network, but still, I had to add the exception in firewall, thus I expected, that IComputingModuleAdminProvider would not be available over http protocol.ยจ
UPDATE:
Ass suggested by Otiel, if I create new ServiceContract like this:
public class ComputingModuleAdminProvider : IComputingModuleAdminProvider
And mark it as a new <service> in App.Config, I can separate the admin and standard interface.
Related
One of my mate has created a C# WCF service working on Net.TCP on a specific port, it is asked to me if it is possible to create an other endpoint on this WCF service in order to consume it with HTTP protocol on the same port ?
How can I do to consume a WCF service with two differents protocols Net.TCP + HTTP ?
Thanks per advance for your answers :)
Edit : Do you have an example about how to implement a HTTP + Net.TCP endpoints in a WCF service ?
As far as I know, this is completely impossible. But service could work properly over Net.TCP+Http over different port number.
<services>
<service name="ConsoleApp3.TestService">
<endpoint address="" binding="netTcpBinding" contract="ConsoleApp3.ITestService" ></endpoint>
<endpoint address="http" binding="basicHttpBinding" contract="ConsoleApp3.ITestService"></endpoint>
<endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange"></endpoint>
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:21012"/>
<add baseAddress="http://localhost:21013"/>
</baseAddresses>
</host>
</service>
</services>
Net.TCP Port sharing only is applicable for the scenario that has different service addresses, not the indeed port sharing.
Feel free to let me know if there is anything I can help with.
I have a simple Webserivce (WCF) hosted in a Windows Service(Selfhost). The declaration of the service looks like this :
<service behaviorConfiguration="MyApp.ServiceImplementation.MyAppIntegration_Behavior" name="MyApp.ServiceImplementation.MyAppIntegration">
<endpoint binding="basicHttpBinding" bindingConfiguration="BasicMyAppIntegration" bindingNamespace="MyApp.ServiceImplementation" contract="MyApp.ServiceContracts.IMyAppIntegration"/>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
<host>
<baseAddresses>
<add baseAddress="http://localhost:8008/MyAppServiceutv/Integration"/>
</baseAddresses>
</host>
</service>
I can brows the WSDL with this URL :
http://localhost:8008/MyAppServiceutv/Integration?wsdl
When adding the service reference in Visual Studio 2012 I get this exception :
Exception
The document was understood, but it could not be processed.
The WSDL document contains links that could not be resolved.
There was an error downloading 'http://localhost:8008/MyAppServiceutv/Integration?xsd=xsd0'.
Unable to connect to the remote server
Metadata contains a reference that cannot be resolved: 'http://MyComputer:8008/MyAppServiceutv/Integration?wsdl'.
Content Type application/soap+xml; charset=utf-8 was not supported by service http://MyComputer:8008/MyAppServiceutv/Integration?wsdl. The client and service bindings may be mismatched.
The remote server returned an error: (415) Cannot process the message because the content type 'application/soap+xml; charset=utf-8' was not the expected type 'text/xml; charset=utf-8'..
If the service is defined in the current solution, try building the solution and adding the service reference again.
Moving to Dev Environment
When moving the service to a dev computer everything works just great? Why whould I get the above problems in just one environment? Could this be due to strong security restrictions?
It sounds like your VS2012 instance is off box from your service host machine. Try changing your config like this...
<service behaviorConfiguration="MyApp.ServiceImplementation.MyAppIntegration_Behavior" name="MyApp.ServiceImplementation.MyAppIntegration">
<endpoint binding="basicHttpBinding" bindingConfiguration="BasicMyAppIntegration" bindingNamespace="MyApp.ServiceImplementation" contract="MyApp.ServiceContracts.IMyAppIntegration"/>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
<host>
<baseAddresses>
<add baseAddress="http://{my fully qualified domain name}:8008/MyAppServiceutv/Integration"/>
</baseAddresses>
</host>
</service>
Okay. Now I have confirmed the problem...an explanation. .net 4.0 or less WCF produces multi-file WSDL files. The base WSDL file links to various files. The link that is in your WDSL file links to the other files using absolute URIs as opposed to relative URIs. So when your Visual Studio tries to find the other WDSL files it fails to find it on "localhost".
With .net 4.5 WCF can generate SINGLE FILE WSDL which will also solve your problem. But overall in my opinion WCF 4.0 is broken when dealing with WSDL proxy generation.
I have a WCF service being hosed by a Windows Service with this in the app.config
<services>
<service behaviorConfiguration="serviceBehavior" name="AgileServer.AgileService">
<endpoint address="AgileService" binding="basicHttpBinding" name="basicHttp" contract="AgileServer.AgileService" />
<endpoint binding="mexHttpBinding" name="mex" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:24453/AgileService" />
</baseAddresses>
</host>
</service>
When I try to add a service reference to my service (by clicking "Discover" in the "Add Service Reference" prompt), the URI shows up as http://localhost:33908/AgileService.svc I want my service to use http://localhost:24453/AgileService as the URI. How can I accomplish this?
You need to
have the WCF service in your Windows service up and running
do not click on Discover, but instead type in / paste in the URL you want to connect to - either use the base address (http://localhost:24453/AgileService) or the MEX endpoint's address (http://localhost:24453/AgileService/mex)
Doing this will connect to the URL defined, and the service metadata will be retrieved and used to create a client-side proxy for the service.
Just as a side-note: your actual service URL will be:
http://localhost:24453/AgileService/AgileService
made up of your base address (http://localhost:24453/AgileService) plus the relative address on the endpoint (AgileService).
I have a windows service on my laptop, which hosts a WCF service. I would like to use these service on my ASP.NET website, which is on external ASP.NET server.
Could you help me, how to do this?
Is it necessary a specific laptop configuration for that? What should I configure?
And binding, what type will adequate? .. Right now, I've got:
<service behaviorConfiguration="WcfServices.InfoBehavior" name="MyProgram.WcfServices.Info.Info">
<endpoint address="" binding="wsHttpBinding" contract="MyProgram.WcfServices.Info.IInfo">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8732/Info/" />
</baseAddresses>
</host>
</service>
UPDATE:
Right now, my client app is still on my laptop (it is not publish yet).. This is my client code:
<client>
<endpoint address="http://localhost:8732/Info/" binding="wsHttpBinding"
bindingConfiguration="WSHttpBinding_IInfo" contract="ServiceInfo.IInfo"
name="WSHttpBinding_IInfo">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
</client>
I don't know, what binding use.. what port, what settings should be changed on my laptop?
Unless your laptop has its own fixed IP address exposed externally (most unlikely) I think you will find it hard to do this directly.
You might consider using Azure Service Bus to broker message exchanges: I believe this is one way to solve the problem of accessing a service hosted on a non-constant IP address or behind a firewall/NAT.
Or you could consider changing your design to turn things the other way around. That is, when it is connected and running, your laptop service connects to a service hosted on the ASP.NET box, over a duplex binding, with your current service contract as the callback contract.
If you have a WCF service running on your laptop hosted via ServiceHost you'll need to duplicate that configuration in your ASP.NET web.config file, as well as add a "service.svc" file which is referenced to the Interface of your service.
You should change localhost with real external facing IP address of your laptop and it could work if your router at home has no firewall. Change it in both client and server endpoint address.
I feel like this question is so basic that none of the tutorials or documentation even bothers to mention how to do it. I'm familiar with web services on other platforms, but I'm new to WCF services.
I've set up a wsHttpBinding like this (in the web.config):
<service behaviorConfiguration="IdentityServiceBehavior" name="Com.CompanyName.Service.IdentityService">
<endpoint address="/Identityservice" binding="wsHttpBinding"
bindingConfiguration="" contract="Com.CompanyName.Service.IIdentityService" />
<endpoint address="mex" binding="mexHttpBinding" bindingConfiguration=""
bindingNamespace="" contract="IMetadataExchange" />
</service>
I attempt to hit the URL using Fiddler or just a browser and it just gives me a 400 result. I've tried a bunch of different possibilities for what the URL might be, but no dice. I've tried this URL and a few variations on it: http://localhost:61987/IdentityService.svc/Identityservice
If anyone could point me in the direction of the basic information I'm missing here, I'd be very grateful.
You can use the WCF test client to test your WCF services