Take the 2-minute tour ×
SharePoint Stack Exchange is a question and answer site for SharePoint enthusiasts. It's 100% free, no registration required.

I would like to call an external WCF Service from within SharePoint 2010. Using normal WCF calls immediately causes a SocketException (An existing connection was forcibly closed by the remote host), which can be circumvented with SPSecurity.RunWithElevatePrivileges.

[SocketException (0x2746): An existing connection was forcibly closed by the remote host]
System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags) +85
System.ServiceModel.Channels.SocketConnection.ReadCore(Byte[] buffer, Int32 offset, Int32 size, TimeSpan timeout, Boolean closing) +204

[CommunicationException: The socket connection was aborted. This could be caused by an error processing your message or a receive timeout being exceeded by the remote host, or an underlying network resource issue. Local socket timeout was '00:00:58.7210000'.]
System.ServiceModel.Channels.SocketConnection.ReadCore(Byte[] buffer, Int32 offset, Int32 size, TimeSpan timeout, Boolean closing) +15307563
System.ServiceModel.Channels.SocketConnection.Read(Byte[] buffer, Int32 offset, Int32 size, TimeSpan timeout) +90
System.ServiceModel.Channels.DelegatingConnection.Read(Byte[] buffer, Int32 offset, Int32 size, TimeSpan timeout) +34
System.ServiceModel.Channels.ConnectionStream.Read(Byte[] buffer, Int32 offset, Int32 count, TimeSpan timeout) +34
System.ServiceModel.Channels.ConnectionStream.Read(Byte[] buffer, Int32 offset, Int32 count) +88
System.Net.FixedSizeReader.ReadPacket(Byte[] buffer, Int32 offset, Int32 count) +58
System.Net.Security.NegotiateStream.StartFrameHeader(Byte[] buffer, Int32 offset, Int32 count, AsyncProtocolRequest asyncRequest) +62
System.Net.Security.NegotiateStream.StartReading(Byte[] buffer, Int32 offset, Int32 count, AsyncProtocolRequest asyncRequest) +54
System.Net.Security.NegotiateStream.ProcessRead(Byte[] buffer, Int32 offset, Int32 count, AsyncProtocolRequest asyncRequest) +402

[IOException: The read operation failed, see inner exception.]
System.Net.Security.NegotiateStream.ProcessRead(Byte[] buffer, Int32 offset, Int32 count, AsyncProtocolRequest asyncRequest) +704
System.Net.Security.NegotiateStream.Read(Byte[] buffer, Int32 offset, Int32 count) +154
System.ServiceModel.Channels.StreamConnection.Read(Byte[] buffer, Int32 offset, Int32 size, TimeSpan timeout) +87

[CommunicationException: The socket connection was aborted. This could be caused by an error processing your message or a receive timeout being exceeded by the remote host, or an underlying network resource issue. Local socket timeout was '00:00:58.7210000'.]
System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg) +10257978
System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type) +539
MyApp.FunctionThatCallsService()

That got me thinking: SharePoint does it, and they do it in a nice way where they have individual service configurations in 14\WebClients.

I reflected and cloned a lot of it (The Extension Methods on the ChannelFactory are used internally all over the place - SPChannelFactoryOperations), but I wonder: Are the "proper" APIs that SharePoint uses to call it's own WCF Services exposed to external code, so that I can call my non-SharePoint WCF Services from custom SharePoint code?

(This is a farm solution deployed to the GAC, so neither CAS nor Sandboxing applies)

Edit: Added some clarification and callstacks

share|improve this question

3 Answers 3

Check this reference implementation from SharePoint Patterns and Practices Group: http://msdn.microsoft.com/en-us/library/ff798482.aspx

They have downloadable sample solution too.

share|improve this answer
    
That's for sandboxed solutions and requires excessive plumbing. Do you know if there is a more straight-forward solution for non-Sandboxed solutions? –  Michael Stum Jul 11 '11 at 20:23
    
Michael, check the code that makes the WCF-call. That can help you –  Bas Lijten Jul 15 '11 at 14:41

You should have a look at Eric White's article around calling WCF External Web Services from SharePoint 2010 which use Claims based authentication. The process is absolutelly the same whether you consume or not the services via BCS.

See here the series link http://blogs.msdn.com/b/ericwhite/archive/2010/06/18/consuming-a-claims-enabled-wcf-web-service-as-an-sharepoint-2010-external-content-type.aspx

Hope it helps, C:\Marius

share|improve this answer
up vote 0 down vote accepted

Ended up keeping the SPSecurity.RunWithElevatedPrivileges section. Microsoft's SPChannelFactoryOperations at some point hit a NullReferenceException, most likely due to Claims required to be setup within the service even when not using it (SPServiceAuthenticationMode only has SPServiceAuthenticationMode.Claims as a member. The fact that CreateChannelActingAsLoggedOnUser() immediately throws an ArgumentException is a signal that the SPChannelFactoryOperations aren't meant to be used by non-Microsoft code.

share|improve this answer
    
The SPChannelFactoryOperations are only used for claims aware services. aobut the security exception: are you sure that you current identity (logged on user) has sufficient rights to call the wcf-service? And took care of the double hop issue? Calling SPSecurity.RunWithElevatedPrivileges gets rid of the "double-hop" and calls your wcf-service as the app-Pool account –  Bas Lijten Jul 18 '11 at 8:49
    
@Bas yes, the user does have permission. I've run Wireshark on the target server, and the call doesn't even make it to that server. Is ASP.net impersonation enforcing any other security constraints on the call? –  Michael Stum Jul 18 '11 at 17:45

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.