What is wrong with my Silverlight / WCF Configuration - c#

I've been struggling for a few hours I admit. I must be missing something with the Bindings/Configuration between my Silverlight application and WCF web service. It was working for awhile, but I must have accidentally changed some settings and I can't get it to work anymore.
In Visual Studio when I debug I have both the Service and Silverlight application launch at the same time, I have Windows authentication disabled in the web.config files for debugging. When I deploy, I go back and change my Configuration files to enable Windows security/transport so I can get user credentials on the web service side.
Now when I deploy both the WCF service and the Silverlight application to a different machine using IIS, I get an error "Not Found" from Silverlight when it attempts to contact the WCF service. Could someone explain to me the different configuration files that exist and what each should be pointing to? Here are my configuration files in their respective locations:
wwwroot\webserviceapp\web.config
<?xml version="1.0" encoding="UTF-8"?>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpEndpointBinding">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Windows"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
<services>
<service behaviorConfiguration="ServiceBehavior" name="WebserviceName.Service1">
<endpoint address="" binding="basicHttpBinding"
bindingConfiguration="BasicHttpEndpointBinding"
name="BasicHttpEndpoint" contract="WebserviceName.IService1">
</endpoint>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" aspNetCompatibilityEnabled="true" />
wwwroot\web.config - this is the web.config for silverlight I guess?
<?xml version="1.0" encoding="UTF-8"?>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpEndpoint" 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="TransportCredentialOnly">
<transport clientCredentialType="Windows" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://<<<ip_to_machine>>>/webserviceapp/Service1.svc"
binding="basicHttpBinding"
bindingConfiguration="BasicHttpEndpoint"
contract="ServiceReference1.IService1"
name="BasicHttpEndpoint" />
</client>
</system.serviceModel>
<system.webServer>
<defaultDocument>
<files>
<add value="ProjectTestPage.html" />
</files>
</defaultDocument>
</system.webServer>
wwwwroot\ClientBin\SilverlightApp.xap (the ServiceReferences.ClientConfig file):
<configuration>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpEndpoint" maxBufferSize="2147483647"
maxReceivedMessageSize="2147483647">
<security mode="TransportCredentialOnly" />
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://<<<ip_to_machine>>>/webserviceapp/Service1.svc"
binding="basicHttpBinding"
bindingConfiguration="BasicHttpEndpoint"
contract="ServiceReference1.IService1"
name="BasicHttpEndpoint" />
</client>
</system.serviceModel>
These are the three configuration files which seem to drive everything, unless I am wrong? Since I develop on one environment and deploy to another it seems like I must change these files to point to the right resources. When I hit my Silverlight application after I've deployed it to the new machine I get the application loading. Once it finishes loading, the first web service call it makes fails with exception and I get this in the Chrome Console:
Failed to load resource: the server responded with a status of 500 (Internal Server Error) http://<<<ip_to_machine>>>/webserviceapp/Service1.svc
Failed to load resource: the server responded with a status of 500 (Internal Server Error) http://<<<ip_to_machine>>>/webserviceapp/Service1.svc
Uncaught Error: Unhandled Error in Silverlight Application An exception occurred during the operation, making the result invalid. Check InnerException for exception details. at System.ComponentModel.AsyncCompletedEventArgs.RaiseExceptionIfNecessary()
at Project.ServiceReference1.GetAllNewsCompletedEventArgs.get_Result()
at Project.View.Home1.ClientGetAllNewsCompleted(Object pSender, GetAllNewsCompletedEventArgs pEventArgs)
at Project.ServiceReference1.Service1Client.OnGetAllNewsCompleted(Object state)
I'm like 99% certain that the Service is NEVER hit. I have a log statement at the very top of the function which is being called and it never logs anything.
IIS Configuration:
Web Service Authentication:
Anonymous = Disabled
ASP.NET Impersonation = Disabled
Windows Authentication = Enabled
Default Web Site (where my silverlight app is hosted):
Anonymous = Disabled
ASP.NET Impersonation = Disabled
Windows Authentication = Enabled
Anyone have any suggestions, or need anymore information from me to help debug?
EDIT: It is worth noting that I am able to navigate to the service from a different machine and see the service wsdl just fine. For example:
http://ipaddress/webserviceapp/Service1.svc
I can see this just fine, no errors.

I think the answer is pretty simple. The error I was receiving is a very generic error. The proper thing to do in this instance is to use Fiddler which will tell you EXACTLY what the error is. In my case, Trace logging wasn't working properly due to the service not loading properly. However, Fiddler was able to give me the exact exception messages which led me to resolve the problem quickly and easily.

Related

WCF Service Metadata Exchange over TCP

I created a WCF Service hosted on IIS. With HTTP binding everything ist working fine. But when I switch to TCP binding it doesn't work any more. I tried every hint I found on the web, but no success.
Already done:
installed Windows-Feature "WCF-Non-Http-Activation"
activated Windows Service Net.Tcp-Listener Adapter
In WcfTestClient the service can't be added. But maybe this tool doesn't support TCP(?) so I also tested in Visual Studio by trying to add a service reference.
Error Message when trying to add the service in VS:
An error occurred while attempting to find services at 'net.tcp://hostname:19099/Namespace/Company.Service.svc/mex'. No IPEndpoints were found for host hostname. Details: Metadata contains a reference that cannot be resolved: 'net.tcp://hostname:19099/Namespace/Company.Service.svc/mex'.
This is my current web.config (anonymized) - what am I doing wrong?
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.web>
<compilation targetFramework="4.8"/>
<httpRuntime targetFramework="4.8"/>
<customErrors mode="Off"/>
</system.web>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceMetadata />
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="Company.Namespace.Service" behaviorConfiguration="ServiceBehavior">
<endpoint name="ServiceEndpoint" address="" binding="netTcpBinding"
bindingConfiguration="ServiceNetTcpBinding" contract="Company.Namespace.IService"/>
<endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange"/>
<host>
<baseAddresses>
<add baseAddress="net.tcp://hostname:19099/Namespace/Company.Service/"/>
</baseAddresses>
</host>
</service>
</services>
<bindings>
<basicHttpBinding>
<binding name="ServiceBasicHttpBinding" sendTimeout="00:01:00" receiveTimeout="00:01:00" openTimeout="00:01:00" closeTimeout="00:01:00"/>
</basicHttpBinding>
<netTcpBinding>
<binding name="ServiceNetTcpBinding" sendTimeout="00:01:00" receiveTimeout="00:01:00" openTimeout="00:01:00" closeTimeout="00:01:00"
transferMode="Buffered" transactionFlow="false" hostNameComparisonMode="StrongWildcard" listenBacklog="10" maxBufferPoolSize="524288"
maxBufferSize="65536" maxConnections="10" maxReceivedMessageSize="65536" portSharingEnabled="false" transactionProtocol="OleTransactions">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384"/>
<reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false"/>
<security mode="Transport">
<message clientCredentialType="None"/>
<transport clientCredentialType="Windows" protectionLevel="EncryptAndSign"/>
</security>
</binding>
</netTcpBinding>
<wsHttpBinding>
<binding name="ServiceWsHttpBinding" sendTimeout="01:00:30" receiveTimeout="01:00:30"/>
</wsHttpBinding>
</bindings>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https"/>
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"/>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<directoryBrowse enabled="true"/>
</system.webServer>
</configuration>
When you say that you cancel the maximum number of connections and it works, does that mean that the maximum number of connections limits your network?
As far as I know, IIS 5/6 does not support non-HTTP services. IIS7 supports Net TCP, but you must install WAS first. Refer to the following steps:
Control Panel -- Programs and Features -- Turn Windows features on or off and install WAS.
Check whether non-HTTP support is enabled for WCF. Select the same interface in .NET Framework.
Add the Net TCP binding to the site and enable the Net TCP protocol.
Further details can also be found in this docs.

Sending X.509 certificates to WCF c#

I have a WCF service which uses such behaviors:
<behavior name="WCFServiceCertificate.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"/>
<serviceCredentials>
<clientCertificate>
<authentication certificateValidationMode="ChainTrust"/>
</clientCertificate>
<serviceCertificate findValue="localhost" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName"/>
</serviceCredentials>
</behavior>
It uses a certficate named "localhost" which I created by makecert. First I created Root Certification Authority and then a certificate. I generated also a client certificate which was saved in a file.
Then, I have a client application which consumes that webservice. App.config consists of:
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IWS">
<security>
<message clientCredentialType="Certificate" />
</security>
</binding>
</wsHttpBinding>
</bindings>
And I load the cerificate for client from a file:
X509Certificate2 client = new X509Certificate2("client.pfx", "pass");
All certificates' stuff seem to be done properly, but when I want to invoke any service method from the client, it says:
The caller was not authenticated by the service
Could someone, please, give me some advice on how to pass the certificate in SOAP header properly from the client to server? What do I miss?
Working with certificate is not an easy task specially for debugging it in WCF. For this reason you may consider the following steps to narrow down your problem.
Does your Service run after you embed certificate? One way to test if it is working properly is to try hitting your service in your browser.
Ex. http://localhost/Path/Service.svc
Are you accessing the service address in your client same as what is describe in CN=localhost certificate?
Ex. http://location/Path/Service.svc
And not this :
Ex. http://computername/Path/Service.svc
Or
Ex. http://computername.domain.com/Path/Service.svc
Explanation :
Certificate will not work if the name in the Common Name of certificate is different in the URL name issued to that certificate.
Are you in the same machine? Certificate with CN=localhost will only work in same machine.
Since you host your Service in IIS you need to configure your IIS to use the certificate you created and bind it in port 443.
How?
Go to you IIS and Client Default Web Site
Click Binding location at the right side
If protocol HTTPS is already configure try to edit it and assign your certificate. If not, Add the protocol HTTPS with port 443 and assign your certificate. Certificate should visible in the list if you installed properly in the store.
Through these steps we may able to know where to start. It could be at service problem, client problem or IIS configuration. Hope this will help us both to solve your problem.
I am struggling with the issue all the time. I reconfigured both client and the server side.
Web.config (server):
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="wsHttpEndpointBinding">
<security>
<message clientCredentialType="Certificate" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<services>
<service name="WSInfo.WS" behaviorConfiguration="WCFServiceCertificate.Service1Behavior">
<!-- Service Endpoints -->
<endpoint address="" binding="wsHttpBinding" bindingConfiguration="wsHttpEndpointBinding" contract="WSInfo.IWS">
<!--
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="WCFServiceCertificate.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"/>
<serviceCredentials>
<clientCertificate>
<authentication certificateValidationMode="ChainTrust"/>
</clientCertificate>
<serviceCertificate findValue="ForServer"
storeLocation="LocalMachine"
storeName="My"
x509FindType="FindBySubjectName" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
And app.config (WinForms Client App):
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IService1" 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="Certificate" negotiateServiceCredential="true"
algorithmSuite="Default" establishSecurityContext="true" />
</security>
</binding>
<binding name="WSHttpBinding_IWS">
<security>
<message clientCredentialType="Certificate" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://XX.XX.XXX.XXX:XX/WSInfo/WS.svc" behaviorConfiguration="CustomBehavior"
binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IService1"
contract="WSInfo.IWS" name="WSHttpBinding_IWS">
<identity>
<dns value="ForServer" />
</identity>
</endpoint>
</client>
<behaviors>
<endpointBehaviors>
<behavior name="CustomBehavior">
<clientCredentials>
<clientCertificate findValue="Client" x509FindType="FindBySubjectName" storeLocation="CurrentUser" storeName="My" />
<serviceCertificate>
<authentication certificateValidationMode="ChainTrust"/>
</serviceCertificate>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
I generated certificates in an application called XCA. First, on the server I generated the root cerificate and a certficate for client. I exported it and imported on client machine. Then I generated the root certificate on the client machine and the next certificate for server. I exported it and imported in server's system. I think the configuration files are OK, but maybe something's wrong with certificates - when I want to invoke a method from the client I get "The caller was not authenticated by the service". I tried to add HTTPS with my certificate but it resulted in problems with connection to IIS. Now IIS is off... I'll look up the solution but please verify if my configs are OK.

The remote server returned an error: (413) Request Entity Too Large

Please do NOT delete this message as a duplicate!!
I am writing a WCF service that allows for XML files to be uploaded so that they can be imported into the database. However I am receiving the above error when I upload a file above the 64k default.
I have read through all the questions already posted on here about this problem and implemented them but still am facing the same issue.
I have increased all the binding values in my config file (for both the client and server) to accept the maximum size of 2GB.
<binding name="BasicHttpBinding_BailiffServices"
maxBufferSize="2147483647"
maxBufferPoolSize="2147483647"
maxReceivedMessageSize="2147483647">
<readerQuotas maxDepth="2147483647"
maxStringContentLength="2147483647"
maxArrayLength="2147483647"
maxBytesPerRead="2147483647"
maxNameTableCharCount="2147483647" />
&ltsecurity mode="None" />
Here are the WCF services that use this binding.
<services>
<service name="ClientService.ClientService">
<endpoint address="http://subversion/BusinessTier.Services.ClientService.svc"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_BailiffServices"
name="BasicHttpBinding_IClient" contract="ClientService.IClient" />
</service>
<service name="DebtorService.DebtorService">
<endpoint address="http://subversion/BusinessTier.Services.DebtorService.svc"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_BailiffServices"
name="BasicHttpBinding_IDebtor" contract="DebtorService.IDebtor" />
</service>
</services>
I have also added settings to the config to ensure that IIS is also able to handle large files.
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<security>
<requestFiltering allowDoubleEscaping="true">
<requestLimits maxAllowedContentLength="2147483647"/>
<fileExtensions allowUnlisted="true"/>
<verbs allowUnlisted="true"/>
</requestFiltering>
</security>
</system.webServer>
As far as I can see I have amended all the necessary settings to allow my WCF service to accept large files, but none of them have so far worked.
Any suggestions would be greatly appreciated.
I found solution to avoid error like 'The remote server returned an unexpected response: (413) Request Entity Too Large.'
When using basicHttpBinding in WCF Service Configuration You just need to increase the maximum message length in the Web.config.following way you can update you server web.config and client app.config file for sending large byte array via wcf.
Include following bindings and behaviors parameters in Web.config
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding maxReceivedMessageSize="2147483647" sendTimeout="00:10:00" receiveTimeout="00:10:00">
<readerQuotas maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647"/>
</binding>
</basicHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="false">
<serviceActivations>
<add factory ="WebService.NInjectServiceHostFactory" relativeAddress="TestServic.svc" service="WebService.Services.ServiceManager"/>
</serviceActivations>
</serviceHostingEnvironment>
I have also added binding configuration in client app.config file.
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IServiceManager" maxBufferSize="2147483647" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647">
<security mode="None"/>
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647"/>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:49359/ServiceManager.svc"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IPackageManager"
contract="PackageManager.IPackageManager" name="BasicHttpBinding_IPackageManager" />
</client>
</system.serviceModel>
this will also handle timeout error as well.
I've eventually managed to get this working after several hours of head scratching. I removed the binding name "BasicHttpBinding_BailiffServices" from both the <binding /> element and the <endpoint /> elements. I stumbled across this solution on the MSDN site. Hope this helps someone else.

Sporadic exceptions calling a web service that is load balanced

I have a web service that I am running on three load balanced web servers and I am getting sporadic errors. Now, I admit that the load balanced part may be a bit of a red herring, but when I test with only 1 web server I cannot reproduce the error. If I test with all three web servers I can get the error (but it is not 100% of the time, more like 50%). All testing is done through the load balancer, we just tell the load balancer how many servers we want to farm.
The code is simple single request code. That is, there is no state. A request is made and a response is returned. The web service code is c# .NET 4 running on IIS 7.5. The client code is both a web site and a desktop app.
I get one of two exceptions:
System.ServiceModel.Security.MessageSecurityException:
An unsecured or incorrectly secured
fault was received from the other
party. See the inner FaultException
for the fault code and detail. --->
System.ServiceModel.FaultException:
The security context token is expired
or is not valid. The message was not
processed.
Or I get:
System.ServiceModel.Security.SecurityNegotiationException:
Secure channel cannot be opened
because security negotiation with the
remote endpoint has failed. This may
be due to absent or incorrectly
specified EndpointIdentity in the
EndpointAddress used to create the
channel. Please verify the
EndpointIdentity specified or implied
by the EndpointAddress correctly
identifies the remote endpoint. --->
System.ServiceModel.FaultException:
The request for security token has
invalid or malformed elements.
As you can see from the following snips from my .config files, I am not using security as this is strictly an internal web service. (names have been changed to protect the innocent--namely me).
Server Side:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- Service Side web.config -->
...
<system.serviceModel>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
<services>
<service behaviorConfiguration="InternalUseOnly.InternalUseOnlyServiceBehavior" name="InternalUseOnly.InternalUseOnlyService">
<endpoint address="" bindingNamespace="http://somecompany.com/webservices" binding="wsHttpBinding" contract="InternalUseOnly.IInternalUseOnlyService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="InternalUseOnly.InternalUseOnlyServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
...
</configuration>
Client side
<?xml version="1.0" encoding="UTF-8"?>
<!-- Client Side web.config -->
<configuration>
...
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IInternalUseOnlyService" 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" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://intranet.somecompany.com/InternalUseOnly/InternalUseOnlyService.svc" binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IInternalUseOnlyService" contract="InternalUseOnlyService.IInternalUseOnlyService" name="WSHttpBinding_IInternalUseOnlyService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
</client>
</system.serviceModel>
...
</configuration>
Thoughts anyone?
Additional information: After reviewing the answers below I have tried two things, both without success.
The most obvious change (which I did not notice at first) was to change one of properties on the client to allow cookies <system.serviceModel><bindings><wsHttpBinding><binding name="blah, blah, blah" ... other properties... allowCookies="true" /> It defaults to false. Further, our load balancer uses cookies to keep affinity. But, it did not make a difference (no clue why yet).
Next, I tried various security options in the client side app.config file. This included both <security mode="None" /> and a more elaborate:
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None" />
<message clientCredentialType="None" establishSecurityContext="false" negotiateServiceCredential="false"/>
</security>
although the settings in the last one was just a guess on my part. I did not make any server side changes to the app.config as I don't know what to change and, sadly, I can only test with production as we only have 1 dev web server, not three.
I am going to go out on a limb here and guess that the security involved is the Message security specified on the client side:
<security mode="Message">
<transport clientCredentialType="Windows" proxyCredentialType="None" realm="" />
<message clientCredentialType="Windows" negotiateServiceCredential="true" algorithmSuite="Default" />
</security>
If you are creating a client and connecting, the negotiated windows credential token may be cached. If you don't have sticky sessions enabled, the token might be passed back to the wrong server and will fail. My guess is that its always on the second call?
It is an NTLM problem caused by using load balancers without sticky sessions. To correct the problem you need to configure session affinity (sticky session). If you don't you will get a failure because part of the NTLM handshake happened on one server and the other part happens on another server.
While Chris and Jeff have help get me on the track to an answer, what actually solved it for me was this article i found from Microsoft on Load Balancing Web Services. In short, what we had to do to resolve this for our web farm was to switch from the default wsHttpBinding to basicHttpBinding. This was not difficult, but was an all-or-nothing move. The main web service and every client had to be reconfigured at the same time or it would break.
While wsHttpBinding does have a property of allowCooikes that could be set to true, it apparently does not use them until after the connection is made, at which point the request could jump servers on the first request and thus fail.

Connecting WCF from Webpart

I am consuming a WCF Service from a webpart in Sharepoint 2007. But its giving me the following error:
There was no endpoint listening at
http://locathost:2929/BusinessObjectService
that could accept the message. This is
often caused by an incorrect address
or SOAP action. See InnerException, if
present, for more details. --->
System.Net.WebException: The remote
server returned an error: (404) Not
Found.
My Binding Details in the WCF web.config is:
<system.serviceModel>
<diagnostics performanceCounters="All">
<messageLogging logEntireMessage="true" logMessagesAtServiceLevel="false"
maxMessagesToLog="4000" />
</diagnostics>
<services>
<service behaviorConfiguration="MyService.IBusinessObjectServiceContractBehavior"
name="MyService.BusinessObjectService">
<endpoint address="http://localhost:2929/BusinessObjectService.svc"
binding="wsHttpBinding" contract="MyService.IBusinessObjectServiceContract">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="MyService.IBusinessObjectServiceContractBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
My binding details in the Sharepoint site web.config is:
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IBusinessObjectServiceContract"
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="Mtom" 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" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:2929/BusinessObjectService.svc"
binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IBusinessObjectServiceContract"
contract="BusinessObjectService.IBusinessObjectServiceContract"
name="WSHttpBinding_IBusinessObjectServiceContract">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
</client>
</system.serviceModel>
I am able to view the WCF (and its wsdl) in browser, using the URL given in the end point. So, I guess the URL is definately correct. Please help !!!
I've replicated your code and it runs correctly for me, but there are a couple of discrepencies.
Firstly, the server side configuration you've supplied is not complete. The endpoint mex fails because I don't have the IMetadataExchange contract. When you browse to the WSDL, this is presumably the endpoint you are viewing.
I'm just removing this endpoint altogether. Following from this, I'm specifying an address for the serviceMetadata element in the behavior like this:
<serviceMetadata httpGetEnabled="true" httpGetUrl="http://localhost:2929/BusinessObjectService.svc?wsdl" />
Not ideal but it works to let me discover the service. Then my generated client config file is the same as yours, except...
Secondly, I have messageEncoding="Text" instead of messageEncoding="Mtom"
Try changing messagingEncoding to Text. You haven't specified on server side that it should be Mtom so I don't understand why it has been generated on client side as Mtom.
Apart from these two issues my configuration is the same as yours, and it runs without a problem. I'm not sure that the second issue I've identified is a real issue at all (I can't see how the metadata exchange would give the wrong message encoding), but the first issue is stopping the service from running on my side.
I got an error that looked almost identical as the described error. However my error was a 503 and I was calling a web service on an external server.
When I called the service from a standalone app I had no problems, but when I called the service from a web part in SharePoint it failed.
Solutions that worked me, without any further explanation because I haven't really digged into why it works (If you know, please enlighten me :))
1st solution that worked for me was to use my own domain account instead of the service account for the application pool that was used by the SPWebApplication.
2nd solution was to set the service binding attribute UseDefaultWebProxy to false
UseDefaultWebProxy = false
Of course these solutions depends on your proxy settings and user settings. My proxy settings was setup to bypass proxy for the service I was calling, so my suspicion is that the proxy settings (configured here: IE->Internet Options->Connections->LAN settings) doesn't apply to the service account but only to the logged in user. By now, this is what I'll investigate more.
EDIT 1:
Hmm. that was actually not bringing anything new to the table, I used psexec to view my proxy settings as the service account (netsh->winhttp->show proxy) and that looked correct, so I don't think this could be the issue.
EDIT 2:
Final solution, so the problem was that my SP web app was not using the proxy settings I had setup in IE when the app pool was run in the context of a service account, when I used my user account for the app pool I had no problems and the proxy settings in IE was used. After a little more investigation it appeared that I could define proxy settings for my SPWebApplication in web.config and I chose just to disable the proxy
<system.net>
<defaultProxy enabled="false" />
</system.net>

Categories

Resources