I would like to call an external WCF Service from within SharePoint. 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)
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With