Подтвердить что ты не робот

Как правильно вызвать внешнюю службу WCF из SharePoint 2010?

Я хотел бы вызвать внешнюю службу WCF из SharePoint. Использование обычных вызовов WCF сразу вызывает SocketException (существующее соединение было принудительно закрыто удаленным хостом), которое можно обойти с помощью SPSecurity.RunWithElevatePrivileges.

[SocketException (0x2746): существующее соединение было принудительно закрыто удаленным хостом]
   System.Net.Sockets.Socket.Receive(буфер Byte [], смещение Int32, размер Int32, гнездо сокета SocketFlags) +85
   System.ServiceModel.Channels.SocketConnection.ReadCore(буфер Byte [], смещение Int32, размер Int32, тайм-аут TimeSpan, булевское закрытие) +204

[CommunicationException: соединение сокета было прервано. Это может быть вызвано ошибкой обработки вашего сообщения или превышением времени приема удаленным хостом или проблемой сетевого ресурса. Локальный тайм-аут гнезда был "00: 00: 58.7210000".]
   System.ServiceModel.Channels.SocketConnection.ReadCore(буфер Byte [], смещение Int32, размер Int32, тайм-аут TimeSpan, логическое закрытие) +15307563
   System.ServiceModel.Channels.SocketConnection.Read(буфер байта [], смещение Int32, размер Int32, тайм-аут TimeSpan) +90
   System.ServiceModel.Channels.DelegatingConnection.Read(буфер байта [], смещение Int32, размер Int32, тайм-аут TimeSpan) +34
   System.ServiceModel.Channels.ConnectionStream.Read(буфер байта [], смещение Int32, количество Int32, тайм-аут TimeSpan) +34
   System.ServiceModel.Channels.ConnectionStream.Read(буфер байта [], смещение Int32, количество Int32) +88
   System.Net.FixedSizeReader.ReadPacket(буфер Byte [], смещение Int32, количество Int32) +58
   System.Net.Security.NegotiateStream.StartFrameHeader(буфер Byte [], смещение Int32, количество Int32, AsyncProtocolRequest asyncRequest) +62
   System.Net.Security.NegotiateStream.StartReading(буфер Byte [], смещение Int32, количество Int32, AsyncProtocolRequest asyncRequest) +54
   System.Net.Security.NegotiateStream.ProcessRead(буфер Byte [], смещение Int32, количество Int32, AsyncProtocolRequest asyncRequest) +402

[IOException: операция чтения не удалась, см. внутреннее исключение.]
   System.Net.Security.NegotiateStream.ProcessRead(буфер Byte [], смещение Int32, количество Int32, AsyncProtocolRequest asyncRequest) +704
   System.Net.Security.NegotiateStream.Read(буфер Byte [], смещение Int32, количество Int32) +154
   System.ServiceModel.Channels.StreamConnection.Read(буфер байта [], смещение Int32, размер Int32, тайм-аут TimeSpan) +87

[CommunicationException: соединение сокета было прервано. Это может быть вызвано ошибкой обработки вашего сообщения или превышением времени приема удаленным хостом или проблемой сетевого ресурса. Локальный тайм-аут гнезда был "00: 00: 58.7210000".]
   System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg) +10257978
   System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData & msgData, тип Int32) +539
   MyApp.FunctionThatCallsService()

Это заставило меня подумать: SharePoint это делает, и они делают это с хорошим способом, когда у них есть индивидуальные конфигурации сервисов в 14\WebClients.

Я размышлял и клонировал много его (методы расширения на ChannelFactory используются внутри страны повсюду - SPChannelFactoryOperations), но мне интересно: "правильные" API, которые SharePoint использует для вызова собственных WCF-сервисов, подверженных внешнему коду, чтобы я мог вызывать мои не-SharePoint WCF-сервисы из пользовательского кода SharePoint?

(Это решение фермы, развернутое в GAC, поэтому не применяются ни CAS, ни Sandboxing)

4b9b3361

Ответ 1

Закончено сохранение раздела SPSecurity.RunWithElevatedPrivileges. Microsoft SPChannelFactoryOperations в какой-то момент попадает в исключение NullReferenceException, скорее всего, из-за требований, требуемых для настройки внутри службы, даже если она не используется (SPServiceAuthenticationMode имеет только SPServiceAuthenticationMode.Claims в качестве члена. Тот факт, что CreateChannelActingAsLoggedOnUser() немедленно бросает ArgumentException - это сигнал, что SPChannelFactoryOperations не предназначены для использования кодом, отличным от Microsoft.