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?).
Related
I'm just getting familiar with WCF and I have to add additional functionality to a working web service at work. As I feel the need to be able to test the functionality before deploying it, I decided to build a test client. Here comes the problem.
I created a Console Application just for the purpose of a test client and tried to add a Service Reference through the provided WSDL but it didn't work. There was no config file created.. I tried first the "Add Service Reference" option in VS and when it didn't work, I tried creating the Proxy and Config files with svcutil.exe...
Just the proxy class gets created... When I try to instantiate a "client object" from that class, the following Exception is thrown: "Could not find default endpoint element that references contract 'eOrderingService.IeOrderingService' in the ServiceModel client configuration section. This might be because no configuration file was found for your application, or because no endpoint element matching this contract could be found in the client element."
As this is a working service (a Czech company is using it), apparently there must be a way to create a web.config or app.config even manually but I have no idea where to start.. As I said I'm just getting familiar with WCF so I started looking online but most of the problems connected somehow to my issue were in different parts of the already created Config files.. I managed to bypass that exception adding the following to app.config:
<system.serviceModel>
<services>
<service name="eOrderingService" >
<endpoint
address="http://localhost:61472/eOrderingService.svc"
binding="webHttpBinding"
contract="eOrderingService.IeOrderingService" >
</endpoint>
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="web">
<webHttp helpEnabled="true" />
</behavior>
</endpointBehaviors>
</behaviors>
<client>
<endpoint
address="http://localhost:61472/eOrderingService.svc"
binding="webHttpBinding"
bindingConfiguration=""
contract="eOrderingService.IeOrderingService"
behaviorConfiguration="web"
name="DeliveryNote" >
</endpoint>
</client>
The service has a lot of methods and the one I need to test is called 'DeliveryNote'.
So lets say the service is at this address:
http://localhost:61472/eOrderingService.svc
The POST method I need to call is:
http://localhost:61472/eOrderingService.svc/DeliveryNote
And respectively the GET method is:
http://localhost:61472/eOrderingService.svc/DeliveryNote?DocumentFilter={DOCUMENTFILTER}&CustomerID={CUSTOMERID}&FromDate={FROMDATE}
The links are working but I cannot figure out how to call them from the client.
When I tested calling the POST method I received another exception:
The remote server returned an unexpected response: (400) Bad Request.
That shouldn't be true because the request I'm sending is already tested and is a valid request in XML format.
So I tried to test with a different GET method that works and receives just two DateTime parameters and not a Xml. If I try the following link:
http://localhost:61472/eOrderingService.svc/PriceChanges?startDate=2018-08-29&endDate=2018-08-30
the result is OK..
But if I call the automatically generated method "PriceChanges" the result is NULL.
I just don't get what I do wrong. It seems like a connection to the service is established but the methods are not called/build correctly. Probably because I cannot comprehend how to build the <system.serviceModel> in app.config.
I definitely should read more about the web services but I don't know where to start.
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 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.
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.
I'm new to WCF and its security so was looking for some help on a problem I'm having.
I have a WCF service that to be deployed to every machine in a small domain. The WCF service is to be hosted in a Windows Service since it has methods in it that need to be invoked elevated. The service is very draft at the moment (it exposes meta-data - but I believe this is to be turned off later - is this possible?). It uses the net.tcp binding - The App.Config of the service is shown below:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<services>
<service behaviorConfiguration="SvcBehavior" name="Microsoft.ServiceModel.Samples.Svc">
<endpoint address="" binding="netTcpBinding"
contract="Microsoft.ServiceModel.Samples.ISvc" />
<endpoint address="mex" binding="mexTcpBinding" bindingConfiguration=""
contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="net.tcp://*:8100/ServiceModelSamples/service" />
</baseAddresses>
<timeouts closeTimeout="00:10:00" openTimeout="00:10:00" />
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="SvcBehavior">
<serviceMetadata httpGetEnabled="false" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
For a client, I have a Winforms C# application. The application serves 2 functions, it pulls static information from the service and then gives the user an option to authenticate and call the administrative methods. Therefore, the authentication is done at client level.
I am using Channelfactory to connect to the service since the hostname is variable (user is prompted for it on client start-up) and the app.config file for the client is shown below - its virtually empty:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<bindings>
</bindings>
<client />
</system.serviceModel>
</configuration>
The channelfactory code is:
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
[System.ServiceModel.ServiceContractAttribute(Namespace = "http://Microsoft.ServiceModel.Samples", ConfigurationName = "ISvc")]
ChannelFactory<ISvc> myChannelFactory = new ChannelFactory<ISvc>(new NetTcpBinding(), "net.tcp://" + HostName + ":8100/ServiceModelSamples/service");
public static ISvc client = null;
I have an interface that descrives the methods in the service as well.
The main problem I am having is this. Say there is Machine1 and Machine2 running on domainA. Lets assume that Machine1 hosts the service and Machine2 runs the client.
When I connect to the service using a domain account domainA\User, the service works fine but say I have a local user on Machine2 and want to connect to the service as Machine2\LocalUser, I get the following error message:
The server has rejected the client credentials.
I have tried experimenting with setting the security mode to none (not something im keen on doing) but then I get an error saying the client and service have a configuration mismatch.
Is there something I can do to fix this? Also, what would happen if the service running on domainA\Machine1 was called by a user from another domain - say domainB\User2 ?
Thanks in advance - Id appreciate some insight into this!
Chada
If you turn off security on the service you must turn in off on the client as well. If you configure client in code you must set the same configuration for new instance of NetTcpBinding as you do on the service in configuration file.
When Windows security is used (default for NetTcpBinding) MachineB cannot authenticate local accounts from MachineA (there were some tricks with duplicate local users but I don't know if they work with WCF as well). That is why you have a domain. Cross domain windows authentication requires trust between domains.
If you need to authenticate cross domain users or local users you cannot use Windows authentication. There are other authentication mechanism but they require configuring certificate (at least on the service) and use either client certificate or user name and password for client authentication.