Calling webservice from WCF service - wcf

I am having an issue consuming a webservice (c#.net) from a WCF service.
The error i am getting is EndPointNotFoundException "TCP error code 10061: No connection could be made because the target machine actively refused it"
I wrote a unit test to check if i could send a request to the web service and it worked fine
[The unit test is using the same binding configuration as my WCF service]
The web service and WCF service (client) have basichttp binding.
Did anyone had similar kind of issue calling a webservice from a WCF service?
The service Model section is as follows
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="DataService" closeTimeout="00:05:00" openTimeout="00:05:00" receiveTimeout="00:10:00" sendTimeout="00:05:00" allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536" messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered" useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384"/>
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None" realm=""/>
<message clientCredentialType="UserName" algorithmSuite="Default"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://10.22.33.67/Service/DataService.asmx" binding="basicHttpBinding"
bindingConfiguration="DataService" contract="Service.DataService" name="DataService"/>
</client>
<services>
<service name="TestToConsumeDataService.WCFHost.Service1" behaviorConfiguration="TestToConsumeDataService.WCFHost.Service1Behavior">
<!-- Service Endpoints -->
<endpoint address="" binding="basicHttpBinding" contract="TestToConsumeDataService.WCFHost.IService1">
<!--
Upon deployment, the following identity element should be removed or replaced to reflect the
identity under which the deployed service runs. If removed, WCF will infer an appropriate identity
automatically.
-->
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="TestToConsumeDataService.WCFHost.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="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
The unit test project is also using the same service model section and it works. The only issue is while calling the service from another WCF service. Could you please suggest.

You mentioned "webservice" and "WCF service" - so the "webservice" is a old-style ASMX web service??
How is your WCF service hosted? In IIS? Do you have the necessary endpoint information for the webservice you're calling from WCF inside your web.config ??
Can you show us your relevant configs, e.g. the <system.serviceModel> section of your web.config (or app.config, if you're self-hosting the WCF service), please?
The error means there's either no webservice listening at the address you're using, or you don't have access rights to it. Are you missing some security or something?
MArc

It looks like there is some configuration that you need to call your web service.
This configuration is correct in the configuration file of your unit test.
But it is not correct or missing in the configuration file of your WCF service.
When you have two dll's where one calls the other, then it is the config file of the first dll that is used. However, when you go over a WCF hop, it is the config file of the WCF service that takes over.
Hope this helps
Shiraz

Related

Generate a WCF client proxy for a netstandard Xamarin.Forms project

I've created a Xamarin.Forms project with a netstandard2.0 targeting library instead of a shared or PCL library. So far this compiles and works. I'm using an up2date version of Visual Studio 2017 Community.
I also have created a WCF service that gonna be hosted on windows itself (not IIS). I've configured my app.config to provide a Metadata Exchange Endpoint:
<?xml version="1.0"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
</startup>
<system.serviceModel>
<services>
<service behaviorConfiguration="MM.Server.ServiceServerBehavior" name="MM.Server.ServiceServer">
<endpoint address="net.tcp://localhost:8730/MMServer/" binding="netTcpBinding" bindingConfiguration="NetTcpBinding_IServiceServer" bindingName="NetTcpBinding_IServiceServer_EndPoint" contract="MM.Contracts.IServiceServer">
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<endpoint address="http://localhost:8731/MMServer/mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:8730/MMServer/"/>
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="MM.Server.ServiceServerBehavior">
<serviceMetadata httpGetEnabled="true" httpGetUrl="http://localhost:8731/MMServer/mex" />
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<netTcpBinding>
<binding name="NetTcpBinding_IServiceServer" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" transactionFlow="false" transferMode="Buffered" transactionProtocol="OleTransactions" hostNameComparisonMode="StrongWildcard" listenBacklog="10" maxBufferPoolSize="2147483647" maxBufferSize="2147483647" maxConnections="10" maxReceivedMessageSize="2147483647">
<readerQuotas maxDepth="32" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="16384"/>
<reliableSession ordered="true" inactivityTimeout="01:00:00" enabled="false"/>
<security mode="None"><!-- TODO: Add more security later -->
<transport clientCredentialType="None" protectionLevel="None"/>
</security>
</binding>
</netTcpBinding>
</bindings>
</system.serviceModel>
</configuration>
This is a very simple configuration and I don't care about security for now. The service runs, successfully.
Now I cannot simply add a service reference to my Xamarin.Forms project, since netstandard does not provide System.ServiceModel.
I've found out that I can use the SLsvcUtil.exe from the Silverlight SDK to generate the client proxy for my WCF service that is compatible to Xamarin.Forms targeting netstandard instead, however I cannot get it running.
No matter how I try to use the SLsvcUtil.exe while my WCF service is running, I always get the error:
Error: An error occurred in the tool.
Error: Object reference not set to an instance of an object.
Here is my batch that I used to execute SLsvcUtil.exe:
set "namespace=*,MM.Services"
set "mexPath=http://localhost:8731/MM/mex"
set "svcutil=C:\Program Files (x86)\Microsoft SDKs\Silverlight\v5.0\Tools\SLsvcUtil.exe"
set "outputDir=C:\vsproj\Xamarin\MM\MM.App"
"%svcutil%" %mexPath% /directory:"%outputDir%" /namespace:"%namespace%"
pause
http://localhost:8731/MM/mex returns the full WSDL, successfully.
How can I get a working generated client proxy for my Xamarin.Forms app that is targeting netstandard2.0? I'm open for any alternative that leads to the same desired result.
Take a look at the official Microsoft WCF client for .NET Core. I think this should work also with Xamarin since it is designed for .NET Core.
GitHub .NET Core WCF Client Libraries
Web Service Reference guide
Microsoft WCF Web Service Reference Provider

How to consume WCF Service with net tcp binding and without mex binding

I installed a windows application, it uses a WCF service, I just go through the config file for WCF service with net tcp binding hosted in Windows service with the following configuration, I am wondering how the clients are able to consume this WCF service. Application consumes this service to populate data in the UI, and it works. When I try to consume this I am not able to do so through WCF test client. Then how the application consumes this service?
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="NetTcpBinding_FirstBindingServiceContract" closeTimeout="00:10:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:10:00"
transactionFlow="false" transferMode="Buffered" transactionProtocol="OleTransactions"
hostNameComparisonMode="StrongWildcard" listenBacklog="10"
maxBufferPoolSize="999999999" maxBufferSize="999999999" maxConnections="10"
maxReceivedMessageSize="999999999">
<readerQuotas maxDepth="999999999"
maxStringContentLength="999999999"
maxArrayLength="999999999"
maxBytesPerRead="999999999"
maxNameTableCharCount="999999999" />
<reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false" />
<security mode="Transport">
<transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" />
<message clientCredentialType="Windows" />
</security>
</binding>
</netTcpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="MyServiceBehaviors">
<serviceMetadata />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="MyService.DataAccessService" behaviorConfiguration="MyServiceBehaviors">
<endpoint bindingConfiguration="NetTcpBinding_FirstBindingServiceContract"
name="firstBinding" address="net.tcp://localhost:25488/MyDataAccessService/MyFirstBindingAddress"
binding="netTcpBinding"
contract="MyDataService.IMyDataAccessService">
</endpoint>
</service>
</services>
</system.serviceModel>
You need to know three things to call a WCF service:
Address - where to call to - in your case net.tcp://localhost:25488/MyDataAccessService/MyFirstBindingAddress
Binding - what protocol and parameters to use (in your case: netTcpBinding)
Contract - the service contract (the public interface IMyDataAccessService) to define the service methods and parameters needed
Once you have these things, you can easily set up a client in code:
NetTcpBinding binding = new NetTcpBinding(NetTcpBinding.None);
EndpointAddress address = new EndpointAddress("net.tcp://localhost:25488/MyDataAccessService/MyFirstBindingAddress");
ChannelFactory<IMyDataAccessService> channelFactory = new ChannelFactory<IMyDataAccessService>(binding, address);
IMyDataAccessService _clientProxy = channelFactory.CreateChannel();
and now your _clientProxy can easily call up the methods on the server, passing in the parameters etc.
Of course, for this to work, you must have the contract! E.g. you must have access to the file that define the service contract (and possibly the data contracts, too - the data types being sent back and forth). Since you're using the netTcpBinding, I'm assuming both ends of the wire are built using .NET here.
Those items can easily be included into a separate class library project that both the service developers as well as the client-side developers can share and use.

SSL, WCF service hosted on internal domain, consuming app resides in DMZ

Background info:
I have some WCF services that are hosted on an internal server on a specific port. A hole was "punched" in the firewall to make the services on this port accessible from the DMZ. The consuming web app is hosted in the DMZ.
The internal server DOES NOT have an SSL cert.
The DMZ server DOES have an SSL cert.
The problem:
From all that I have read about WCF, my understanding is that I need an SSL cert on the server that hosts the WCF services. Is this correct?
At this time I have been told that we don't know when the internal server will have an SSL cert installed and that I need to come up with a Plan B.
I started looking into going back to ASMX/WSE and it looks like that is going to be a problem since WSE is no longer supported, it does not integrate with VS2008 and it is not compatible with x64 machines.
[rock]Me[hardplace]
The data will contain PII, so I'm quite considered about security...even if others are less concerned.
Are there any options I've overlooked? Have I misunderstood WCF security?
Advice?
This post seems somewhat similar.
UPDATE
Thanks to mikey's answer and comments I made some changes to my configuration. It took some trial and error and additional Googling...but it seems to be working now (I haven't performed any extensive testing yet). However, I don't know if this is sufficiently secure...
Adding my solution to the original post so I can mark mikey's answer as the answer.
My changes
Services:
<behaviors>
<serviceBehaviors>
<behavior name="serviceBehavior">
<dataContractSerializer maxItemsInObjectGraph="6553600" />
<!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
<serviceMetadata httpsGetEnabled="false" />
<!-- 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="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<wsHttpBinding>
<binding name="customBinding">
<reliableSession enabled="true" />
<security mode="None" />
</binding>
</wsHttpBinding>
</bindings>
<services>
<service behaviorConfiguration="serviceBehavior" name="MyApp.WcfServices.MyService">
<endpoint address="" binding="wsHttpBinding" bindingConfiguration="customBinding" contract="MyApp.WcfServices.IMyService">
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
Web App:
<bindings>
<wsHttpBinding>
<binding name="customBinding" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="1048576" maxReceivedMessageSize="1048576"
messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="true" />
<security mode="None">
<transport clientCredentialType="None" />
<message clientCredentialType="None" negotiateServiceCredential="false" establishSecurityContext="false" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://[Ip Address]:8943/MyAppWcfServices/Hosts/MyService.svc"
binding="wsHttpBinding" bindingConfiguration="customBinding"
contract="MyService.IMyService" name="customBinding" behaviorConfiguration="clientBehavior">
</endpoint>
</client>
Here are some options:
You don't need SSL for WCF. You can set security to "None" http://msdn.microsoft.com/en-us/library/ms731172.aspx or http://social.msdn.microsoft.com/forums/en-US/wcf/thread/271b1816-173c-4c76-a4c4-fd9fda4b5e91/ -- then you won't need an SSL cert. Since the traffic is only going between your web server and your app/wcf server the only folks who will be able to sniff it should be internal folks... At some point you have to trust your network is working as intended. I often use only HTTP (not SSL) for web services between app and web servers on the same network especially when speed is an issue.
use a self-signed certificate on the app server. Ensure that the web server in the DMZ is configured to trust the certificate (and/or its CA) and you should be good to go.

WCF: Could not find default endpoint element that references contract 'IService' in the ServiceModel client configuration section. when hosting in IIS

I have a WCF service which is being hosted in IIS. I have a WCF client also (a console application). I have used svcutil to build the proxy class and configuration file and then added those to my client project. It built properly. But when I tried to run the program, it is throwing the below exception
Could not find default endpoint element that references contract 'IService' 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.
//My client program code
namespace MyFirstWCFClient
{
class Program
{
static void Main(string[] args)
{
ServiceClient objClient = new ServiceClient();
Console.WriteLine("Client calling the service....");
string strName=Console.ReadLine();
Console.WriteLine(objClient.HelloWorld("Shyju"));
Console.Read();
}
}
}
Output.config file of my client is
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IService" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
allowCookies="false">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="false" />
<security mode="Message">
<transport clientCredentialType="Windows" proxyCredentialType="None"
realm="" />
<message clientCredentialType="Windows" negotiateServiceCredential="true"
algorithmSuite="Default" establishSecurityContext="true" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost/IISHostedserviceTest/Service.svc"
binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IService"
contract="IService" name="WSHttpBinding_IService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
</client>
</system.serviceModel>
</configuration>
and in the web.config of my service has the below configuration
<system.serviceModel>
<services>
<service name="Service" behaviorConfiguration="ServiceBehavior">
<!-- Service Endpoints -->
<endpoint address="http://localhost/IISHostedserviceTest/Service.svc" binding="wsHttpBinding" contract="IService">
<!--
Upon deployment, the following identity element should be removed or replaced to reflect the
identity under which the deployed service runs. If removed, WCF will infer an appropriate identity
automatically.
-->
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<!-- 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="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
I used this(http://www.wcftutorial.net/WCF-IIS-Hosting.aspx) tutorial to have a try on WCF.
Can anyone guide me how to resolve this ?
Quick question: if your client app is called myclient.exe, is your config in the same directory as the EXE and called MyClient.exe.config ?
You can't just take the output.config from svcutil - you will need to either add a app.config to your client console project (which will be renamed to myclient.exe.config when compiling), or you need to copy/rename the output.config to myclient.exe.config in order for your client app to find and use it.
You have to use the constructor for the client that specifies the endpoint configuration name, eg.
objClient = new ServiceClient ("WSHttpBinding_IService");
That will tell the proxy to use the configuration you specified in the config file.
I had a similar problem with 2 WCF services connecting one to another.
After generating output.config + MyService.cs class files with the svcutil.exe and copying them to the solution dir I had the same problem.
Just found an answer to this problem: You have to copy whole "bindings" tag to your main config file inside "ServiceModel" tag AND copy your referenced endpoint next to existing endpoints in your main config file - that solved the exception problem for me
Another approach to take would be to add a Service Reference to your IIS hosted service. Visual Studio will automatically run svcutil in the background and do the configuration work for you - i.e. it'll create the app.config for you.
Doing it manually is fine, but I suggest running it at least once by adding a Service Reference just to see it work properly.

WCF Client not able to negotiate security access with Service running in a different machine

I'm trying to host a WCF Service with binding "wsDualHttpBinding". When I run my client and service(hosted in IIS) from the same machine it works fine. But, when I host the service in a different machine my client fails to register with the service. The following errors are coming...
[System.ServiceModel.Security.SecurityNegotiationEception]
The caller was not authenticated by
the service. And inner exception: The
request for security token could not
be satisfied because authentication
failed.
When trying to run from a different machine in another workgroup the following error appears
"Client is unable to finish the
security negotiation within the
configured time(00:00:00)"
In the IIS6.0 I turned off the Integrated Authentication and allowed anonymous access.
My Service's Web.Config follows:
<system.serviceModel>
<diagnostics>
<messageLogging logMalformedMessages="true" logMessagesAtServiceLevel="true" logMessagesAtTransportLevel="true"/>
</diagnostics>
<bindings>
<wsDualHttpBinding>
<binding name="StatTickerHttpBinding" bypassProxyOnLocal="false" useDefaultWebProxy="true" receiveTimeout="23:59:59">
<reliableSession ordered="true" inactivityTimeout="00:30:00"/>
</binding>
</wsDualHttpBinding>
</bindings>
<services>
<service name="StatTickerService" behaviorConfiguration="ServiceBehavior">
<!-- Service Endpoints -->
<endpoint address="" binding="wsDualHttpBinding" bindingConfiguration="StatTickerHttpBinding" contract="IBroadCastService">
<!--
Upon deployment, the following identity element should be removed or replaced to reflect the
identity under which the deployed service runs. If removed, WCF will infer an appropriate identity
automatically.
<identity>
<dns value="localhost"/>
</identity> -->
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<!-- 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="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
My Client App.Config follows...
<system.serviceModel>
<bindings>
<wsDualHttpBinding>
<binding name="WSDualHttpBinding_StatTickerBroadcastService"
closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384"/>
<reliableSession ordered="true" inactivityTimeout="00:30:00"/>
<security mode="Message">
<message clientCredentialType="Windows" negotiateServiceCredential="true" algorithmSuite="Default"/>
</security>
</binding>
</wsDualHttpBinding>
</bindings>
<client>
<endpoint address="http://192.168.100.77/TPS.StatTicker.WCFservice/Service.svc" binding="wsDualHttpBinding"
bindingConfiguration="WSDualHttpBinding_StatTickerBroadcastService"
contract="BroadcastGateway.StatTickerBroadcastService"
name="WSDualHttpBinding_StatTickerBroadcastService">
<identity>
<servicePrincipalName value="host/192.168.100.77"/>
</identity>
</endpoint>
</client>
</system.serviceModel>
The Client side config is done by using svcutil.
I searched and tried all the solutions given in the google for the past 4 days but no luck. Please help urgently.
If I understand your issue, it sounds like you're having problems with delegation.
Here's what I think you're trying to do:
User connects to web service
User authenticates with windows authentication (kerberos)
Webserver impersonates user
Webserver connects to backend via WCF
Webserver authenticates with backend using the user's credentials (kerberos)
Backend accepts credentials and serves up data
What needs to happen is your backend has to trust your web server to act on your behalf, called delegation. This is controlled by the domain and not freely given.
If both machines are on the same domain, the domain controller has to configure the web server as able to delegate for users. Without this, no machines on the network will trust your web server acting on a user's behalf. If this all takes place on the same machine, it does its own delegation.
If both machines are in a workgroup, I don't know what you would do.
I think you need to specify a security of "none" in the server's web.config. Otherwise it would default to insisting on an authentication mechanism.
Try this:
<identity>
<servicePrincipalName value=""/>
</identity>