Sporadic exceptions calling a web service that is load balanced - c#

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.

Related

WebAPI Certificates and Authentication - ELI5

I'm sure I'm missing some key facts, but I can get those for you. I'm really confused on how this all needs to work:
Server 1 – IIS 8, Hosting a Vendor’s WebAPI, Anonymous and Windows Authentication. Providers are Negotiate, NTLM. Https and a signed certificate (Cert1).
Server 2 – IIS8, New WebAPI connecting to Server1’s WebAPI. I’m assuming I need to store Cert1 on Server 2. We will have another Certificate, https (Cert2)
Server 3 – IIS 8, Website connecting to server 2’s webAPI.
User – Browser connecting to Server 3, Windows Authentication Only.
Every server and the user’s browser connects to the same Active Directory.
I have access to Server1’s web.config to change bindings, but not the code. In Visual Studio 2013, when I add the service reference for Server 2, the web.config is added like this:
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_ICoreWebService">
<security mode="Transport">
<transport clientCredentialType="Windows" proxyCredentialType="None" realm="" />
<message clientCredentialType="Certificate" negotiateServiceCredential="true" algorithmSuite="Default" establishSecurityContext="true" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="https://dave.domain.com/webService/CoreWebService.svc" binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_ICoreWebService" contract="Dave.ICoreWebService" name="WSHttpBinding_ICoreWebService">
<identity>
<userPrincipalName value="Server1ServiceAccount#dave.domain.com" />
</identity>
</endpoint>
</client>
This is Server1's WebAPI web.config
<system.serviceModel>
<bindings>
<wsHttpBinding>
<!-- The following block is used for secure connection (HTTPS)-->
<binding name="DaveServiceBinding" maxReceivedMessageSize="2147483647" maxBufferPoolSize="2147483647" receiveTimeout="00:05:00" sendTimeout="00:05:00">
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="None" />
<message clientCredentialType="UserName" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<services>
<service name="Dave.WebService.CoreWebService" behaviorConfiguration="DaveWebServiceBehavior">
<endpoint address="" binding="wsHttpBinding" bindingConfiguration="DaveWebServiceBinding" contract="Dave.WebService.ICoreWebService" />
<endpoint address="wauth" binding="wsHttpBinding" bindingConfiguration="DaveWebServiceBindingWauth" contract="Dave.WebService.ICoreWebService" />
<endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="DaveWebServiceBehavior">
<dataContractSerializer maxItemsInObjectGraph="2147483647" />
<serviceCredentials>
<userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="Dave.WebService.WebServiceAuthValidator,Dave.WebService" />
</serviceCredentials>
<serviceMetadata httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
I’m having trouble with how the certificates work between Server 1 and Server 2. I just need to download Cert1 and store it on Server2? Then refer to that certificate when I make the call. This code isn't finding the certificate:
svc.ClientCredentials.ServiceCertificate.SetDefaultCertificate(StoreLocation.LocalMachine,
StoreName.TrustedPublisher,
X509FindType.FindBySubjectName, "CN = dave.domain.com, OU = ZZ123, O = Dave, Inc., L = Chicago, S = Illinois, C = US");
How can I bubble up the windows authentication from the user to server1? The vendor’s API will Authenticate through that message.
Right now, I’m able to browse to the service locally, but I’ve been stuck on Server 2 and getting the certificate. I want to make sure I’m storing and referencing it correctly.
Thanks in Advance.
The Subject Name needed to be the domain, and I used the MMC to make sure the certificate was where it should be.
MMC -> certificates (you may need to add them in your snap-in)
Trusted People -> Certificates.
Hope that helps someone.

What is wrong with my Silverlight / WCF Configuration

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.

WCF after executing service method. System.ServiceModel.CommunicationException: The remote server returned an error: NotFound

I am getting the error inconsistently,
After successful execution of service method (In between data pass between service & client)
While execution service method itself.
It will execute without causing any issue if the we play with low data [Thousands of data in CSV & DB]
I have google & tried lot in config files, Please help me out if anything need to check in IIS level.
Scenario:
I uploading the file(CSV), which contains 1,00,000 (1 Lakh) records & DB also contains 1 lakh records & the requirement is to compare each record of csv with DB records & give the consolidated output which are the records are different(By comparing each fields).
Client to Service : File is transfered via bytes format
Service to Client : Collection object [Generic List format]
Technologies & Codes used
Entity framework-4 used to fetch initial records.
Used normal foreach/for loop for making comparision.
switch used for field comparision.
WCF, Silverlight, c# & .Net 4.5
Below are my settings,
Service Config:
<basicHttpBinding>
<binding name="basicHttpBinding_IUploadService" maxBufferPoolSize="2147483647" closeTimeout="00:45:00"
openTimeout="00:45:00" receiveTimeout="00:45:00" sendTimeout="00:45:00" maxBufferSize="2147483647"
maxReceivedMessageSize="2147483647">
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647"
maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
<security mode="Transport">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
<service name="Namespace.UploadService">
<endpoint address="" binding="basicHttpBinding" bindingConfiguration="basicHttpBinding_IUploadService"
contract="Namespace.IUploadService" >
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange" />
</service>
<behavior name="">
<serviceMetadata httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
<ServiceErrorBehaviour/>
</behavior>
Client Config:
<binding name="BasicHttpBinding_IUploadService" closeTimeout="00:45:00"
openTimeout="00:45:00" receiveTimeout="00:45:00" sendTimeout="00:45:00"
maxBufferSize="2147483647" maxReceivedMessageSize="2147483647">
<security mode="Transport" />
</binding>
<endpoint address="https://localhost/URL/Upload.svc"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IUploadService"
contract="UploadService.IUploadService" name="BasicHttpBinding_IUploadService" />
Web Config:
<system.web>
<compilation debug="true" targetFramework="4.5"/>
<authentication mode="Windows"/>
<httpRuntime maxRequestLength="2147483647" executionTimeout="2700" enableVersionHeader="false"/>
<pages controlRenderingCompatibilityVersion="4.0" clientIDMode="AutoID"/>
</system.web>
Error:
System.ServiceModel.CommunicationException: The remote server returned an error: NotFound. ---> System.Net.WebException: The remote server returned an error: NotFound. ---> System.Net.WebException: The remote server returned an error: NotFound.
at System.Net.Browser.BrowserHttpWebRequest.InternalEndGetResponse(IAsyncResult asyncResult)
at System.Net.Browser.BrowserHttpWebRequest.<>c__DisplayClassa.<EndGetResponse>b__9(Object sendState)
at System.Net.Browser.AsyncHelper.<>c__DisplayClass4.<BeginOnUI>b__0(Object sendState)
--- End of inner exception stack trace --- & ...
Bytes Size
Client to server(input): 10Mb [In bytes format] &
Server to client(output): if its small amount then fine else issue [expecting morethan input size]
Also using https NOT http.
Thanks,
S.Venkatesh
Silverlight always throws NotFound if the WCF throws an error, because the HTTP response code would be 500: this error code forces Silverlight to throw NotFound.
So, first of all try to debug the WCF while doing this call.
If you can't do that, make the WCF log the error somewhere.
If you like having the correspondent error thrown on the silverlight side, you have to use a server WCF behavior that makes the WCF answer with 200 code even if an error occurred.
More information here:
http://msdn.microsoft.com/en-us/library/ee844556(v=vs.95).aspx
I have encountered similar errors in the past and most of the time it was the WCF Service that was failing to: ex some exception not related to communication part of it.
If its possible debug the WCF Service itself; Alternately you can setup tracing using following utility and make sure that WCF is returning the call properly:
http://msdn.microsoft.com/en-us/library/ms732023.aspx

WCF 4 REST - Multiple Standard Endpoints for Authentication

So I'm attempting to configure a WCF 4 REST app to utilize multiple standard endpoints (for the help functionality). The reason for this is that my hosting IIS process has both Anonymous and Windows Authentication enabled, and certain endpoints within my WCF app require one or the other (both results in an exception).
Previously, I was able to do this by defining some bindings:
<bindings>
<webHttpBinding>
<binding name="Anonymous">
<security mode="None" />
</binding>
<binding name="WindowsAuthentication">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Windows" />
</security>
</binding>
</webHttpBinding>
</bindings>
And then defining the services like so:
<services>
<service name="Host.SubscriberInfoHost">
<endpoint address="" binding="webHttpBinding" bindingConfiguration="WindowsAuthentication" contract="Host.ISubscriberInfoHost" />
</service>
<service name="Utilities.Instrumentation.ServiceStatus.ServiceStatusHost">
<endpoint address="" binding="webHttpBinding" bindingConfiguration="Anonymous" contract="Utilities.Instrumentation.ServiceStatus.IServiceStatusHost" />
</service>
</services>
This is what I've tried to do so far while utilizing the standard endpoints model:
<standardEndpoints>
<webHttpEndpoint>
<standardEndpoint name="Host.SubscriberInfoHost" helpEnabled="true" automaticFormatSelectionEnabled="true">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Windows" />
</security>
</standardEndpoint>
<standardEndpoint name="Utilities.Instrumentation.ServiceStatus.IServiceStatusHost" helpEnabled="true" automaticFormatSelectionEnabled="true">
<security mode="None" />
</standardEndpoint>
</webHttpEndpoint>
</standardEndpoints>
However doing this gets the service confused, as I receive:
System.InvalidOperationException: IIS specified authentication schemes 'Negotiate, Anonymous', but the binding only supports specification of exactly one authentication scheme. Valid authentication schemes are Digest, Negotiate, NTLM, Basic, or Anonymous. Change the IIS settings so that only a single authentication scheme is used
Which is exactly what I'm trying to get away from. Could anyone possibly give me a hand on how I would set this situation up using the new standard endpoints model? Thanks!
Found the answer to this after some experimentation. It turns out that the "name" attribute for standard endpoints is actually an endpoint configuration. So, you would use the following standard endpoints:
<standardEndpoint name="WindowsAuthentication" helpEnabled="true" automaticFormatSelectionEnabled="true">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Windows" />
</security>
</standardEndpoint>
<standardEndpoint name="Anonymous" helpEnabled="true" automaticFormatSelectionEnabled="true">
<security mode="None" />
</standardEndpoint>
And then, you would also configure a service such as the following (the "kind" and "endpointConfiguration" attributes must be set in order to tie this endpoint to the standard endpoint above)
<service name="SomeEndpoint">
<endpoint address="" kind="webHttpEndpoint" endpointConfiguration="WindowsAuthentication" contract="ISomeEndpoint" />
</service>
This allows you to mix authentication styles while maintaining the handy service help page.

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