I am trying to open WCF Service for local use only.
I cant seem to find a way to make it listen on localhost only (not allow remote connections to my WCF host)
Here is an example code :
var baseUri = new Uri("http://127.0.0.1:9001");
var webHost = new WebServiceHost(typeof(MyService), baseUri);
webHost.AddServiceEndpoint(typeof(MyService), new WebHttpBinding(), string.Empty);
webHost.Open();
Console.WriteLine("press any key to exit");
Console.ReadLine();
looking on the resource Monitor shows that it listen to "unspecified ip".
How can i force it to listen on localhost only ?
You can set HostNameComparisonMode on your WebHttpBinding to Exact, this includes the host name in endpoint matching.
The HostnameComparisonMode value that indicates whether the hostname is used to reach the service when matching on the URI. The default value is StrongWildcard, which ignores the hostname in the match.
But using Named Pipes is better in this case. For more info see msdn.
Related
I am using named pipes to communicate between multiple different apps. I have two named pipe hosts which I am trying to get to listen on different addresses.
If I start either app on its own it will run. When i run the second app it will throw and exception telling me that the address is already in use.
System.ServiceModel.AddressAlreadyInUseException: 'Cannot listen on pipe name
'net.pipe://dfb679124c82453888842928c37c6dae/' because another pipe endpoint is
already listening on that name.'
The two services are not using the same address.
I have even setup one of the services with the following code:
Host = new ServiceHost(
this,
new Uri[]
{
new Uri("net.pipe://"+Guid.NewGuid().ToString("N"))
});
var binding = new NetNamedPipeBinding();
Host.AddServiceEndpoint(typeof(IService),
binding, Guid.NewGuid().ToString());
In this code I am generating a random address when the service is created and it still throws the AddressAlreadyInUseException.
I am not using any config configuration to setup the named pipes, everything is code based.
What am I doing wrong?
I need to modify a WCF endpoint binding address. Here is some background on the issue:
I have an NT class service (if it matters, not a webservice). It creates a System.ServiceModel.ServiceHost with an Endpoint whose endpoint address is created this way:
var epa = new EndpointAddress(string.Format("https://localhost:{0}/ServiceAPI/", 8181));
The binding used for the ServiceEndpoint is a WebHttpBinding with Mode=WebHttpSecurityMode.Transport (i.e. https).
When the ServiceHost is opened, I can go to a command prompt, and do "Netstat -a" and see the address bound to the Listen as 0.0.0.0:8181.
So far, no problem. However, a large customer has raised a "security issue" with the fact that because the WCF "listen" is on address 0.0.0.0 instead of 127.0.0.1, that a potential attacker can connect to that address from an external machine. The test that they have constructed is to use telnet 8181 from an external machine, and if the connect occurs, then the test fails. The change request is to modify the service to "listen" on 127.0.0.1:8181 so that the only possibility of connecting to that port is from the local machine.
I have done a fair amount of modifications in an attempt to get WCF to "listen" on "127.0.0.1" instead of "0.0.0.0". In all of my attempts the only way to do this is to set HostNameComparisonMode to "Exact" and create the endpoint address in this way:
var epa = new EndpointAddress(string.Format("https://127.0.0.1:{0}/ServiceAPI/", 8181));
(Actually, as an aside, if I use a different binding such as NetTcpBinding, the above EndPointAddress construction will bind to address "127.0.0.1:8181" without altering HostNameComparisonMode. It only switches internally to "0.0.0.0:8181" when I use WebHttpBinding, and fail to set HostNameComparisonMode=Exact.)
However, this (setting HostNameComparisonMode=Exact) causes a breaking complication due to the fact that existing 3rd party code has already been developed that attempts to (onboard the server) connect to "https://localhost:8181/ServiceAPI", and when HostNameComparisonMode is set to "Exact", WCF only ever returns http error 506 to any request due to the difference between "localhost" and "127.0.0.1".
What I am currently looking for is either a means of setting up WCF to bind to "127.0.0.1:8181" (as determined by netstat -a) with the HostNameComparisonMode still set to the default "StrongWildcard" setting. Or barring any possibility of there being a way to do that, another creative suggestion to cause connects coming from external machines to be unable to connect to that port. (The test would be to use "telnet servername 8181" from a different machine, and it fail to connect.)
Any ideas? Thanks!
if i understand you right, you want to connect from remote machine to this address, so can you try BasicHttpBinding? Also you can try to host it at: "https://localhost:{0}/ServiceAPI/", 8181" Correct pls if i understand you wrong.
Not a duplicate! - The suggested duplicate deals with one using netTcpBinding and one using mexTcpBinding. Read on to see that that is not the case here:
Here's my code:
ServiceHost host = new ServiceHost(class1Type, new Uri(uri));
host.AddServiceEndpoint(interface1Type, new NetTcpBinding(SecurityMode.None), uri);
host.Open();
I have made a copy of the project and am running two instances with one difference - the last character in the uri string. There is nothing in the configuration file. All is in code.
The uri is of the form:
net.tcp://localhost/abc/def
I'm getting an error:
There is already a listener on IP endpoint 0.0.0.0:808. This could
happen if there is another application already listening on this
endpoint or if you have multiple service endpoints in your service
host with the same IP endpoint but with incompatible binding
configurations.
I don’t understand this error, both services are the same, so how can they be incompatible?
All I was missing was:
PortSharingEnabled = true
(I don't think the error message is clear enough.)
I am new WCF programming, I did followed series of Getting Started tutorials from following link
http://msdn.microsoft.com/en-us/library/ms734712.aspx
I have hosted service in console application but when I tried to create a client and tried to add service reference I got the following exceptions.
There was an error downloading
'http: localhost:8000/GettingStarted/mex/_vti_bin/ListData.svc/$metadata'.
The request failed with HTTP status 405: Method Not Allowed. Metadata
contains a reference that cannot be resolved:
'http: localhost:8000/GettingStarted/mex'. There was no endpoint
listening at http: localhost:8000/GettingStarted/mex that could
accept the message. This is often caused by an incorrect address or
SOAP action. See InnerException, if present, for more details. The
remote server returned an error: (404) Not Found. If the service is
defined in the current solution, try building the solution and adding
the service reference again.
code of hosting application
class Program
{
static void Main(string[] args)
{
// Step 1 Create a URI to serve as the base address.
Uri baseAddress =
new Uri("http://localhost:8000/GettingStarted/");
// Step 2 Create a ServiceHost instance
ServiceHost selfHost =
new ServiceHost(typeof(CalculatorService), baseAddress);
try
{
// Step 3 Add a service endpoint.
selfHost.AddServiceEndpoint(typeof(ICalculator),
new WSHttpBinding(),
"CalculatorService");
// Step 4 Enable metadata exchange.
var smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = true;
selfHost.Description.Behaviors.Add(smb);
// Step 5 Start the service.
selfHost.Open();
Console.WriteLine("The service is ready.");
Console.WriteLine("Press <ENTER> to terminate.");
Console.WriteLine();
Console.ReadLine();
// Close the ServiceHostBase to shutdown.
selfHost.Close();
}
catch (CommunicationException ce)
{
Console.WriteLine("exception: {0}", ce.Message);
selfHost.Abort();
}
}
}
Now I am unable to figure out what the problem is. I am using visual studio 2012 and .net platform 4.5.
I had a similar issue as well, messing with this. Yes you seem to have followed the tutorial correctly, but if you want to connect to it and consume as a service (as in make a service reference) you must also add in the MEX service enpoint. Add this line after your selfhost.Description.Behaviors.Add(smb):
selfhost.AddServiceEndpoint(
typeof(IMetadataExchange),
MetadataExchangeBindings.CreateMexHttpBinding(),
"http://localhost:8000/GettingStarted/mex");
That should enable you to connect via "Add Service Reference". Also, I have found depending on your system, you may need to run VS as admin to allow for connection to network (in case you accidentally told it no in the past).
Judging from the error message it seems that there is no service listening at the specified port. You need to have the console application which hosts the service running when you are trying to add a service reference to it.
Apparently, the service is not running which means there is no endpoint listening at the URL you are using to create the service reference.
You can host the service in IIS, or keep the console application running as Damir mentioned above.
Make sure your server is running when you are trying to access it. Also check the configuration on the server and make sure your client's endpoint matches the server's endpoint. Make sure you're using the same binding as well, while you're at it.
Make sure the server is listening and the server's firewall isn't blocking you.
If you made a change to your WCF service don't forget to regenerate the service reference for your client application.
Are you sure you have defined a MEX endpoint? This is what provides metadata information about your service, so that studio can generate a client proxy.
In the tutorial you linked to, it is this bit:
// Step 4 Enable metadata exchange.
ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = true;
selfHost.Description.Behaviors.Add(smb);
If you are hosting the web service in IIS, check in web.config(under behaviours section)
httpsGetEnabled is set to True
I ran into a similar problem today. However, for me it wasn't needed for me to explicitly add the Endpoints, as #iMortalitySX already said.
I had a different reason for failing: I was binding to http://0.0.0.0, thinking the listen IP doesn't matter. Indeed, via SoapUI I was able to connect and to use the Service. But when trying to discover the service in another Visual Studio project, the discovery would fail, as VS would get the initial response, but then follow up links that contained http://0.0.0.0 and then fail.
So changing http://0.0.0.0 into the correct IP of my machine fixed my problem.
Try put the uri address in Your browser. In my case I was able to see an ExceptionDetail.
i want my servicehost to have the base address of any IP
so i tried this
new ServiceHost(typeof(LoggingController),new Uri("0.0.0.0"));
and it gives me invalid URI format
any one knows how should i write this ?
well i tried to access it from outside of my local lan and it didnt work , i made a small test software using tcpiplistener and i started listening to the same port and i set the base address of the tcpip protocol to anyip and the small test software worked so i figured out all i need to do is setting the same for the Webservice –
TcpListener tcpListener = new TcpListener(IPAddress.Any,10021);
this works which also mean my system admin did his job of making sure the port/server is accessable from outside, now shouldnt my webservice work !? it work but i cant access it from outside , i can access it from the same pc if i run client on the same pc
The following code works for me in a similar situation:
Uri baseAddress = new Uri("net.tcp://0.0.0.0:8080/MyService");
host = new ServiceHost(typeof(MyServer), baseAddress);
Reminds me of a problem we had with our software. The default configuration of the webservice used windows network credentials to apply message based security which - due to the domain/network credentials - won't work from another network. Our solution was to disable security on the service binding (which may be a bit tricky depending on the binding you use). For the default bindings like WebHttpBinding it's just passing a parameter in the constructor.
Hope this helps!