Couldn't get metadata from remote machine but local is fine - c#

So here's my App.config:
<?xml version="1.0"?>
<configuration>
<runtime>
</runtime>
<system.serviceModel>
<diagnostics performanceCounters="Default" />
<bindings />
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
<behaviors>
<endpointBehaviors>
<behavior name="CrossDomainServiceBehavior">
<webHttp />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="AService.AServBehavior">
<serviceMetadata httpGetEnabled="false" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="MyService.MyServiceBehavior" name="MyService.MyServ">
<endpoint address="MyService" behaviorConfiguration="" binding="netTcpBinding" contract="AService.IAServ" isSystemEndpoint="false" />
<endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" />
</service>
</services>
</system.serviceModel>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup></configuration>
As you can see there's nothing special. I just want to create simple service with tcp binding and ability to transmit metadata information. I had success with same one using basicHttpBinding and everything was going OK.
Here's the code that creates service instance with baseaddress:
Console.WriteLine("net.tcp://" + _bindAddress + "/");
ServiceHost myserviceHost = new ServiceHost(typeof(MyService), new Uri(String.Concat("net.tcp://", _bindAddress, "/")));
myserviceHost.Open();
_bindAddress is a string that comes from custom service configuration XML file. I'm trying to bind service to internal network interface at IP address 172.19.0.102:8733. Then I'm trying to get service metadata using WcfTestClient from address 127.0.0.1:8733 on service's machine and everyting is fine. But then I trying to obtain service's metadata on target remote machine over Internet I getting the TCP error with code 10051.
My goal is to get service working and publishing metadata over Internet for any client. There's no issues with firewalls and other network stuff. It seems like I need some configuration edits to allow service share metadata with everyone.
Thanks in advance!
POST EDIT:
Here is my tryings:
1) Service configured to bind at 172.19.0.102:8733.
A. WCF Test Client tryes to obtain metadata on hosted machine from address net.tcp://127.0.0.1:8733/ failed with TCP error code 10061.
B. On the same machine WCF Client tryes to obtain metadata from net.tcp://172.19.0.102:8733 and it's working OK.
C. WCF Test Client tryes to obtain metadata on another machine in LAN from address net.tcp://192.168.1.2:8733/ (it's service's machine IP address) gives an error TCP error code 10061.

That error means: Network is unreachable an that is most probably what really happens. Your IP address belongs to private network range and these addresses can never be addressed directly from Internet / WAN - they are only for local usage in LAN. To access such address over internet you must configure your publicly exposed router / gateway to accept the connection and forward it to your internal device = NAT / port forwarding, etc.

Related

Failed to invoke the service. Possible causes: The service is offline or inaccessible while Invoking

I have my service configured as below:
<system.serviceModel>
<services>
<service name="WcfService1.Service1" behaviorConfiguration="MyServiceTypeBehaviors">
<host>
<baseAddresses>
<add baseAddress="net.tcp://127.0.0.1:808/service" />
</baseAddresses>
</host>
<endpoint address="net.tcp://127.0.0.1:808/service/"
binding="netTcpBinding"
contract="WcfService1.IService1"/>
<endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" />
</service>
</services>
<protocolMapping>
<add scheme="net.tcp" binding="netTcpBinding"/>
</protocolMapping>
<behaviors>
<serviceBehaviors>
<behavior name="MyServiceTypeBehaviors">
<serviceMetadata httpGetEnabled="true"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="MyEndpointBehaviour">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
and the client as:
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="NetTcpBinding_IService1" sendTimeout="00:05:00" />
</netTcpBinding>
</bindings>
<client>
<endpoint address="net.tcp://127.0.0.1/service/" binding="netTcpBinding"
bindingConfiguration="NetTcpBinding_IService1" contract="IService1"
name="NetTcpBinding_IService1">
<identity>
<servicePrincipalName value="host/MachineName" />
</identity>
</endpoint>
</client>
</system.serviceModel>
When using WCFTestClient or SVCutil, I am able to discover and access the servie and generate proxy or stubs.
But when I want to invoke any of the methods getting following error:
Failed to invoke the service. Possible causes: The service is offline or inaccessible; the client-side configuration does not match the proxy; the existing proxy is invalid. Refer to the stack trace for more detail. You can try to recover by starting a new proxy, restoring to default configuration, or refreshing the service.
The socket connection was aborted. This could be caused by an error processing your message or a receive timeout being exceeded by the remote host, or an underlying network resource issue. Local socket timeout was '00:04:59.9980468'.
Set the following value inside the endpoint block
<identity>
<dns value ="localhost"/>
</identity>
Maybe not the answer you are looking for, but for development on the local machine I always use an HTTP endpoint. I find Net.TCP will only play nice when it is hosted on a server in IIS.
It is easy enough to add the NET.TCP endpoints once you deploy to an IIS server. Note: that the base address no longer has any affect as that is set in IIS. To test the new endpoints it is best to start by opening the service in a browser while remoted into the server, that way you get the best error messages.
If i understand correctly you are trying to select the endpoint when creating the service reference? Thats now how it works.
If you create your service reference using 127.0.0.1/service/Service1.svc
You should see in your config file something like the following. (When I create my service endpoints I always name them with the protocol as a suffix.
<endpoint address="http://servername:8090/servername/servername.svc/Business"
binding="basicHttpBinding" bindingConfiguration="BusinessHTTP"
contract="servername.IService" name="BusinessHTTP" />
<endpoint address="net.tcp://servername:8030/Service/Service.svc/Business"
binding="netTcpBinding" bindingConfiguration="BusinessTCP"
contract="servername.IService" name="BusinessTCP" />
then in your code you can choose which endpoint to use.
Dim svc as New SeviceReferenceName.BusinessClient("BusinessTCP")"
I have faced the same issue. It was the issue of port address of EndpointAddress. In Visual studio port address of your file (e.g. Service1.svc) and port address of your wcf project must be the same which you gives into EndpointAddress. Let me describe you this solution in detail which worked for me.
There are two steps to check the port addresses.
In your WCF Project right click to your Service file (e.g. Service1.svc) -> than select View in browser now in your browser you have url like http://localhost:61122/Service1.svc so now note down your port address as a 61122
Right click your wcf project -> than select Properties -> go to the Web Tab -> Now in Servers section -> select Use Visual Studio Development Server -> select Specific Port and give the port address which we have earlier find from our Service1.svc service. That is (61122).
Earlier, I had a different port address. After specifying the port address properly, which I got from the first step, EndpointAddress 61122, my problem was solved.
I hope this might be solved your issue.
NetTcp binding is secured by default.In the security authentication process between client and service,WCF ensures that the identity of service matches the values of this element. Therefore service need to be configured with :
<identity>
<dns value ="localhost"/>
</identity>

IIS 7.0 Web Service - Works on HTTP (80), Fails with error 404 on HTTPS (443)

IIS 7.0 on Windows 2008
WCF Web Service, .NET 4 from VS 2010
Web service is installed via publishing and I have full admin rights on the server. There are several complicated methods, but there is a simple one that returns the build version. If we can get this one working, I can fix them all - here is my interface:
namespace MyNameSpace
{
[ServiceContract]
public interface WebInterface
{
[OperationContract]
[WebGet]
string GetVersion();
Attempt to connect via HTTP:// and everything works fine!
Attempt to conenct via HTTPS:// I get a 404 file not found.
I can reach the generic "You have created a web service..." page, including full web service path and the C# generic sample code when browsing to the exact same URL's both on HTTP and HTTPS.
In C#, I have read that the certificate can cause trouble, and I have already implemented the delegate overload to approve our server certificate.
I suspect missing one or more entries in the Web.config file, but I don't have a clue where to start. I have tried Google searching and Stack Overflow searching, but I haven't found the correct combination of search terms to help with this particular issue.
Web Config:
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="HttpGetMetadata">
<serviceDebug includeExceptionDetailInFaults="true"/>
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="LinkService" behaviorConfiguration="HttpGetMetadata">
<endpoint address="" contract="WebInterface" binding="basicHttpBinding" />
</service>
</services>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
Help Please.
You're using the defaults for basicHttpBinding, and the default security mode for that binding is None. You need to define the binding and set the security mode to Transport in your config. Add a Bindings section to your ServiceModel section, like this:
<serviceModel>
<Bindings>
<basicHttpBinding name="secureBinding">
<security mode="Transport">
<transport clientCredentialType="None" />
</security>
</basicHttpBinding>
</Bindings>
</serviceModel>
Then you need to assign this binding to your endpoint via the bindingConfiguration attribute, like this:
<endpoint address=""
binding="basicHttpBinding"
bindingConfiguration="secureBinding"
contract="WebInterface" />
You'll probably want to enable httpsGetEnabled as well:
<serviceMetadata httpGetEnabled="true"
httpsGetEnabled="true" />
See BasicBinding with Transport Security (which is what the sample code is based on).
You can also google with terms like "BasicHttpBinding WCF SSL" and stuff like that - lots of examples and information on the web, it's just a matter of using the right words :)
Also, I'm not 100% confident that the transportClientCredential setting is correct for your scenario (it might need to be Certificate), but I've done very little with SSL for WCF.
There may be other issues as well (like how IIS is set up on your machine), but the above is what's needed for the config.

WCF Impersonation through configuration

I have a simple WCF service that uses WSHttpBinding and Windows authentication. I'm trying to force the server to impersonate the client's identity upon every method call for this service.
I tried the advice given at WCF Service Impersonation, but am not exactly getting happy results. When I try to navigate to the landing page for the WCF service, I see the error:
The contract operation 'GetAdvice'
requires Windows identity for
automatic impersonation. A Windows
identity that represents the caller is
not provided by binding
('WSHttpBinding','http://tempuri.org/')
for contract
('IMagicEightBallService','http://tempuri.org/'.
Any ideas on what this error's trying to tell me?
The entire solution can be browsed at ftp://petio.org/2011/07/01/MagicEightBall/ (or downloaded at http://petio.org/2011/07/01/MagicEightBall.zip). I'm just publishing the project to a local IIS folder and accessing the service at http://localhost/MagicEightBall/MagicEightBallService.svc.
Thanks!
UPDATE:
My service's Web.config:
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<services>
<service name="Petio.MagicEightBall.MagicEightBallService" behaviorConfiguration="MagicEightBallServiceBehavior">
<endpoint name="WSHttpBinding_WindowsSecurity_IMagicEightBallService"
address="http://localhost/MagicEightBall/MagicEightBallService.svc"
binding="wsHttpBinding"
contract="Petio.MagicEightBall.IMagicEightBallService" />
<endpoint address="mex"
binding="mexHttpsBinding"
contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="MagicEightBallServiceBehavior">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
<serviceAuthorization impersonateCallerForAllOperations="true" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
My service code:
public class MagicEightBallService : IMagicEightBallService
{
[OperationBehavior(Impersonation=ImpersonationOption.Required)]
public string GetAdvice()
{
MagicEightBall ball = new MagicEightBall();
return ball.GetAdvice();
}
}
What about minimizing the whole problem to simplest reproducible code which you can simply show here? Nobody is interested in downloading and reviewing whole your project. Moreover for later reference the related code should be still here.
I checked your just configurations of your project and your client code and I see two blocking issues:
If you want to enforce impersonation from configuration you must use only bindings with windows authentication - your endpoint exposed over HTTPS is without authentication.
Impersonation in WCF also requires client to allow service to impersonate his identity so setting the configuration on the service is not enough.
Here you have some article about impersonation and all necessary / possible settings.

WCF with discovery fails with socket not valid in its context on XP?

I'm trying to use WCF's discovery mechanism in .NET 4.0. It works on Windows 7 but fails on an XP machine with a socket exception saying that "the requested address is not valid in its context" (the endpoint is soap.udp://239.255.255.250:3702).
Is the Windows 7 vs XP a red herring? netstat doesn't seem to show any conflicts. What am I missing here?
I've created a simplified test service that shows the problem using the following config:
<configuration>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata/>
<serviceDiscovery />
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior>
<endpointDiscovery />
</behavior>
</endpointBehaviors>
</behaviors>
<services>
<service name="HelloWorldService">
<host>
<baseAddresses>
<add baseAddress="http://localhost/Demo"/>
</baseAddresses>
</host>
<endpoint kind="mexEndpoint" />
<endpoint kind="udpDiscoveryEndpoint" />
<endpoint contract="Test.IHelloWorld"
address="/Hello"
binding="basicHttpBinding" />
</service>
</services>
</system.serviceModel>
</configuration>
There is an issue logged on Microsoft Connect. Unfortunately there is currently no workaround and Microsoft response is
The exception you are mentioning is
normally hit when trying to bind the
socket to an IP address that isn't
valid. Can you please check this and
if possible try on a machine with a
different OS. There are currently no
known limitations of the WCF Discovery
feature on XP.
Is the XP machine behind a firewall or router? To be specific, does the address 239.255.255.250 really belong to the XP machine, or does it actually use a NAT address? Try running ipconfig to see what it thinks it has.

how to bind WCF service to IP address

I am developing a WCF service hosted by IIS, using VSTS2008 + C# + .Net 3.5. I find when reference the service from a client by using Add Service Reference..., client has to be able to resolve the machine name to IP address, because WSDL reference some schema file by machine name. Here is an example of a part of WSDL file, in order to parse WSDL file from client side to generate proxy, we have to be able to resolve machine name testmachine1 to related IP address,
<xsd:import schemaLocation="http://testmachine1/service.svc?xsd=xsd1"
namespace="http://schemas.microsoft.com/2003/10/Serialization/"/>
My question is, for some reason machine name cannot be resolved all the time (for non-technical reasons), so I want to bind to IP address of the hosting IIS server. Is it possible? If yes, appreciate if anyone could advise. Here is my current WCF web.config file, I want to know how to modify it to enable it to work with IP address,
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<services>
<service behaviorConfiguration="Foo.WCF.ServiceBehavior"
name="Foo.WCF.CustomerManagement">
<endpoint address="" binding="basicHttpBinding"
contract="Foo.WCF.ICustomerManagement">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding"
contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="Foo.WCF.ServiceBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
thanks in advance,
George
If your WCF service is hosted in IIS, you cannot set a separate address. You must use the URL of the virtual directory where your SVC file lives - either with a machine name (http://yourserver/virtualdir/myservice.svc) or an IP (http://123.123.123.123/virtualdir/myservice.svc).
If you use the IP to add the service reference, that IP will be used in the WSDL generated by the service import.
If you host the WCF service yourself (Windows service, console app), you can set the service address in config, and use either machine name or IP for the machine.
Marc
I was having this same issue and seen your post while looking for answers to my own problem.
I think I may have found a solution, which was to change the IIS site binding to be that of the ip. I still don't understand why this can't be a setting in the .config file.
Here is the link to the solution that I found (http://blogs.msdn.com/wenlong/archive/2007/08/02/how-to-change-hostname-in-wsdl-of-an-iis-hosted-service.aspx).
Here is a link to my post on my issue (.NET WCF service references use server name rather than IP address causing issues when consuming).
Here is a link to my post about finding the solution (WCF (hosting service in IIS) - machine name automattically being picked up by WCF rather than IP?).

Categories