wsDualHttpBinding not working outside network with WPF Client - wpf

I was trying to implement a DuplexCommunication between WPF and WCF, the communication is working good when test internally, with in the network, when we tried to access this outside network after publishing it outside, we are able to access the service thru web browser, but the WPF client is giving error, when we try to open the connection. below are the configuration on both Server and Client side.
Server:
<wsDualHttpBinding>
<binding 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:10:00" />
<security mode="None" />
</binding>
</wsDualHttpBinding>
<service behaviorConfiguration="DuplexServices.DuplexServiceBehavior" name="DuplexServices.DuplexService">
<endpoint address="dual" binding="wsDualHttpBinding" contract="DuplexServices.IDuplexService" >
</endpoint>
</service>
Client:
<wsDualHttpBinding>
<binding name="WSDualHttpBinding_DuplexService" 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:10:00" />
<security mode="None">
</security>
</binding>
</wsDualHttpBinding>
<client>
<endpoint address="http://XXX.com/DuplexServices/DuplexService.svc/dual"
binding="wsDualHttpBinding" bindingConfiguration="WSDualHttpBinding_DuplexService"
contract="DuplexServiceeReference.DuplexService" name="WSDualHttpBinding_DuplexService">
</endpoint>
</client>
I have tried giving 'baseAddresses' and 'identity' with dns value on server side, also tried giving clientBaseAddress on client side, but still it wont work outside the network.
always getting timeout error when trying to open the duplex connection from WPF application: Error:
"The open operation did not complete within the allotted timeout of 00:00:09.4911018. The time allotted to this operation may have been a portion of a longer timeout."
I think there is something wrong on the config part, but not sure what it is, any help on this much appreciated .
Thanks.

WsDualHttpBinding is not suitable for crossing firewalls - it requires the server open a connection to the client, by default on random address on port 80. The port used can be configured by the clientBaseAddress on the binding but still requires the fire wall to allow inbound connections which, you would hope, the network admins would prevent. If you want to do duplex work in WCF then you should use NetTcpBinding which uses a single outbound connection and the callbacks are performed over this connection
I blogged about this here

Is port 80 open on the client to accept incoming connections, and properly port forwarded through any NAT routers? Dual HTTP Bindings require the server to be able to open a second HTTP connection to the client, and on the Internet (off the LAN) that almost always fails due to firewalls and home routers.

Related

Design WCF service to push data parameters with a byte array?

I have designed the WCF service with operation contracts that can store data in a SQL server database. The operation contract takes parameters such as dataID, dataDescrip., dataType and (byte array) data content. The byte array is originally a file that has to be stored in the database.
I used the WCF service within a web form client application (where the WCF service is referenced) to send the data, but when I send the file >40 kb as a byte array with other parameters it returns bad request 400 error. When I send files less than 30KB or so, the data is successfully stored in DB, no error is returned.
I believe this has to do with large data streaming and changing the size to larger numbers in web.config. I have tried to change the size in the client application web config, but no luck. Also changing the encoding tag to MTOM that returns mismatch client and service binding. I'm using wsHttpBinding.
Not sure what the problem is.
I have read: http://msdn.microsoft.com/en-us/library/ms733742.aspx
but how can I change my current wcf service to enable that while still storing the data to database?
My server config file, App.config from service library is:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.web>
<compilation debug="true" />
</system.web>
<!-- When deploying the service library project, the content of the config file must be added to the host's
app.config file. System.Configuration does not support config files for libraries. -->
<system.serviceModel>
<services>
<service name="IncidentServiceLibrary.IncDataService">
<endpoint address="" binding="wsHttpBinding" contract="IncidentServiceLibrary.IIncDataService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
<host>
<baseAddresses>
<add baseAddress="http://localhost:8732/Design_Time_Addresses/IncidentServiceLibrary/Service1/" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- 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="true" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
<connectionStrings>
.....
</connectionStrings>
</configuration>
The client config file, Web.config in the client I call my service from:
...
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
</system.webServer>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IIncDataService" 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="2147483647" messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false">
<readerQuotas maxDepth="2000000" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2000000" maxNameTableCharCount="2000000" />
<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" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:8732/Design_Time_Addresses/IncidentServiceLibrary/Service1/" binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IIncDataService" contract="IncServiceReference1.IIncDataService" name="WSHttpBinding_IIncDataService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
</client>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" /></system.serviceModel>
</configuration>

WPF application with WCF client/service Could not find endpoint element

Bear with me for a moment, I want to layout the whole picture.
I have a WPF application (.exe) which needs to open and display a window when a COM object (VB6 macro) calls an application method. I've made one managed code project in the .exe solution COM visible and the VB6 macro successfully calls a method on this managed code project (COM stub).
My COM stub receives the method call and runs Process.Start on the WPF exe passing in command line arguments the first time. My application starts as expected. I now need to send data from the VB6 macro, through my COM stub and into the WPF exe on successive calls. I added a WCF project to my WPF exe solution producing a "netNamedPipeBinding" service. I've added a ServiceReference in the COM stub to talk to the WPF exe. I've tested the WCF service separately with a console application and it works. I've built the COM stub ServiceReference using the same Metadata Address as my test cases, and it constructed the reference normally.
My test driver calls the COM stub method and the WPF application starts. My next call to the COM stub tries to instantiate the service client and I get the dreaded error:
"Could not find endpoint element with name 'internal' and contract 'SelectedStudentReference.ISelectedStudent' in the ServiceModel client configuration section."
Here is the contents of my app.config in my WCF service project part of the WPF exe solution.
<system.serviceModel>
<bindings />
<client />
<services>
<service name="AwardManager.Service.SelectedStudentService">
<host>
<baseAddresses>
<!--<add baseAddress = "http://localhost:8080/SelectedStudent" />-->
<add baseAddress="net.pipe://localhost/SelectedStudent" />
</baseAddresses>
</host>
<endpoint
name="internal"
address="net.pipe://localhost/"
binding="netNamedPipeBinding"
contract="AwardManager.Service.ISelectedStudent"
/>
<endpoint
address="mex/pipes"
binding="mexNamedPipeBinding"
contract="IMetadataExchange"
/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="False"/>
<serviceDebug includeExceptionDetailInFaults="False" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
I've tried copying this into the WPF app.config, without success. This service works with a console app test driver. Since this is my first experience with WCF, I'm at a loss for the next troubleshooting step. I looked at another Stackflow question but couldn't figure out if it applied to my case. Any ideas?
It's always the last place you look. My console app test driver was calling the COM stub which carried the ServiceReference. I added this line of code just before the call that created the ServiceClient.
string dir = System.IO.Directory.GetCurrentDirectory();
This showed that the client was being created in the test driver directory. I copied this from my COM stub into the app.config for the test driver. Works like a champ now.
<system.serviceModel>
<bindings>
<netNamedPipeBinding>
<binding name="internal" closeTimeout="00:01:00" openTimeout="00:01:00"
receiveTimeout="00:10:00" sendTimeout="00:01:00" transactionFlow="false"
transferMode="Buffered" transactionProtocol="OleTransactions"
hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="524288"
maxBufferSize="65536" maxConnections="10" maxReceivedMessageSize="65536">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="Transport">
<transport protectionLevel="EncryptAndSign" />
</security>
</binding>
</netNamedPipeBinding>
</bindings>
<client>
<endpoint
address="net.pipe://localhost/"
binding="netNamedPipeBinding"
bindingConfiguration="internal"
contract="SelectedStudentReference.ISelectedStudent"
name="internal">
<identity>
<userPrincipalName value="me#xyz.com" />
</identity>
</endpoint>
</client>
</system.serviceModel>
This led to my solution: move the service ref stuff to the 'main' app.config file,then it can be found by the 'child' (wpf) project.

WPF Client - WCF allow cross-domain access - Issue

I am really struggling with this one. I have Google'd this and tried most of the solutions without any success.
Some background information:
I have a WPF application which consumes a WCF service. Everything works fine if the service and the application is on the same domain, but as soon as you move the application to another domain, it stops wokiring and gives the following error:
The request for security token could not be satisfied because authentication failed.
I worked through the following article: Making a Service Available Across Domain Boundaries[^], which referred to making use of some XML files, which I did, I have tried placing the XML files (clientaccesspolicy.xml and crossdomain.xml) on the IIS server - this did not make any difference (please note that I did place the files within the root of the web service)?!
I can access the web service (client side), by entering the URL in the browser as well as click on the wsdl link and view the XML, but I cannot get it working from my WPF application!
This is my client side config file content:
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IManagmentService" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647"
messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
allowCookies="false">
<readerQuotas maxDepth="32" maxStringContentLength="2147483647"
maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
<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" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://server.local/ManagementDataProvider/ManagmentService.svc"
binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IManagmentService"
contract="ManagementService.IManagmentService" name="WSHttpBinding_IManagmentService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
</client>
</system.serviceModel>
Could anyone please provide me with some information of how I can access the web service from my application.
Many thanks in advance!
Kind regards,
Okay, so the issue was resolved by making use of (http://msdn.microsoft.com/en-us/library/ms731361.aspx). The issue had nothing to do with cross-domain access. The (http://msdn.microsoft.com/en-us/library/ms731299.aspx) needs to be satisfied by the security token, thus accessing the web service from an unknown domain (unknown to the DNS), .
Well, this was what solved my issue?!
Kind regards,

Deploying WCF service and silverlight in SSL

I have an silverlight application with an SSL service. If i deploy the service without SSL all works right, but if i activate the SSL and change the endpoint from http://MyService to https://MyService in the servicereference.clientconfig, and change in web.config:
endpoint from "basicHttpBinding" to "webHttpBinding"
The service dont work and produce the next error:
Unhandled error in silverlight Application [Arg_NullReferenceException]
Arguments: debbuging resource string ar unavalible
I dont know if something is wrong or i need to do something more... etc.
Thanks in advance to everybody i need help.
You can't convert the service endpoint to webHttpBinding because Silverlight only supports basicHttpBinding. To secure your services for Silverlight, you need create a basicHttpBinding with Transport level security. Then, create a service behavior that specifies that httpsGetEnabled="true". I have included a sample below:
Service Side Web.config
<bindings>
<basicHttpBinding>
<binding name="SecureBasicHttpBinding" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01: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="Transport">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<services>
<service name="MyService" behaviorConfiguration="SecureServiceBehavior">
<endpoint address="" binding="basicHttpBinding" contract="IMyService" bindingConfiguration="SecureBasicHttpBinding" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="SecureServiceBehavior">
<serviceMetadata httpGetEnabled="false" httpsGetEnabled="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
Client Side
In the client config, add the same SecureBasicHttpBinding from the services and then add the following endpoint attribute:
bindingConfiguration="SecureBasicHttpBinding"

Silverlight WCF works with BasicHttpBinding, "HTTP 415 Unsupported Media Type" exception when using CustomBinding/BinaryMessageEncoding

I have a silverlight app that talks to a WCF service inside of an ASP.NET website. The following code works:
var service = new ChannelFactory<IService>(new BasicHttpBinding()
{
MaxReceivedMessageSize = int.MaxValue
},
new EndpointAddress(Settings.ServiceUrl)).CreateChannel();
But I really want to take advantage of "binary encoding". To run the service with binary encoding, you cannot use the BasicHttpBinding, you need to use a CustomBinding! The following code is used in the same place, but yields an HTTP 415 Unsupported media type status from the web server. In a debugging session, no breakpoints are reached on the server.
var service = new ChannelFactory<IService>(new CustomBinding(new BinaryMessageEncodingBindingElement(), new HttpTransportBindingElement()
{
MaxReceivedMessageSize = int.MaxValue
}),
new EndpointAddress(Settings.ServiceUrl)).CreateChannel();
I need help finding out why this setting doesnt work! BTW here is the service section in my web config on the server side:
<system.serviceModel>
<bindings>
<customBinding>
<binding name="myBinding">
<binaryMessageEncoding />
<httpTransport authenticationScheme="Negotiate"/>
</binding>
</customBinding>
</bindings>
<services>
<service name="myService">
<endpoint address="" binding="customBinding" bindingConfiguration="myBinding" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="wcfServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
<dataContractSerializer maxItemsInObjectGraph="2147483647"/>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
I figured out how to enable BinaryMessageEncoding, and I can confirm BinaryMessageEncoding works correctly in IIS and visual studio web dev debug server.
The problem was the all-too-common WCF configuration problem. My "service name" was an arbitrary name, but it SHOULD have been the fully qualified name of the service class. Instead of throwing an exception, WCF was exposing the service under some default behavior, and not warning me that the configuration was not valid.
<bindings>
<customBinding>
<binding name="myBinding" >
<binaryMessageEncoding >
<!--readerQuotas are used to set upper limits on message payload-->
<readerQuotas
maxDepth="2147483647"
maxStringContentLength="2147483647"
maxArrayLength="2147483647"
maxBytesPerRead="2147483647"
maxNameTableCharCount="2147483647"
/>
</binaryMessageEncoding>
<httpTransport authenticationScheme="Ntlm" maxReceivedMessageSize="2147483647" maxBufferPoolSize="2147483647"/>
</binding>
</customBinding>
</bindings>
<services>
<!--the service name must be the fully-qualified name of the service class-->
<service name="MyProgram.DataService">
<!--this line allows metatada exchange-->
<endpoint contract="IMetadataExchange" binding="mexHttpBinding" address="mex" />
<endpoint address="" binding="customBinding" bindingConfiguration="myBinding" contract="MyProgram.IDataService" />
</service>
</services>
I don't understand all Silverlight capabilities but at the moment I think your service doesn't work at all. Your custom binding does not have any transport binding element which is mandatory.
Try to change your binding:
<bindings>
<customBinding>
<binding name="myBinding">
<binaryMessageEncoding />
<httpTransport />
</binding>
</customBinding>
</bindings>

Resources