Странное исключение при подключении к службе WCF через прокси-сервер
Исключение " Эта операция не поддерживается для относительного URI. " Возникает в следующей ситуации:
У меня есть сервис WCF:
[ServiceContract(ProtectionLevel=ProtectionLevel.None)]
public interface IMyService
{
[OperationContract]
[FaultContract(typeof(MyFault))]
List<MyDto> MyOperation(int param);
// other operations
}
public class MyService : IMyService
{
public List<MyDto> MyOperation(int param)
{
// Do the business stuff and return a list of MyDto
}
// other implementations
}
MyFault
а также MyDto
два очень простых класса помечены [DataContract]
атрибут, и каждый имеет только три [DataMember]
типа string, int and int?
,
Эта служба размещается в IIS 7.0 на Win 2008 Server вместе с приложением ASP.NET. Я использую файл SVC MyService.svc
который расположен прямо в корне веб-сайта. Конфигурация сервиса в web.config следующая:
<system.serviceModel>
<services>
<service name="MyServiceLib.MyService">
<endpoint address="" binding="wsHttpBinding"
bindingConfiguration="wsHttpBindingConfig"
contract="MyServiceLib.IMyService" />
</service>
</services>
<bindings>
<wsHttpBinding>
<binding name="wsHttpBindingConfig">
<security mode="None">
<transport clientCredentialType="None" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="false"/>
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
Кажется, это работает, поскольку я могу ввести адрес http://www.domain.com/MyService.svc в браузере и получить страницу приветствия "Это служба Windows Communication Foundation".
Одним из клиентов, использующих сервис, является консольное приложение:
MyServiceClient aChannel = new MyServiceClient("WSHttpBinding_IMyService");
List<MyDto> aMyDtoList = aChannel.MyOperation(1);
Он имеет следующую конфигурацию:
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IMyService" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
bypassProxyOnLocal="true" transactionFlow="false"
hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="false"
proxyAddress="10.20.30.40:8080" allowCookies="false">
<readerQuotas maxDepth="32" maxStringContentLength="8192"
maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="false" />
<security mode="None">
<transport clientCredentialType="Windows" proxyCredentialType="None"
realm="" />
<message clientCredentialType="Windows"
negotiateServiceCredential="true" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://www.domain.com/MyService.svc" binding="wsHttpBinding"
bindingConfiguration="WSHttpBinding_IMyService"
contract="MyService.IMyService"
name="WSHttpBinding_IMyService" />
</client>
</system.serviceModel>
Когда я запускаю это приложение на производственном сервере на сайте клиента, звоню aChannel.MyOperation(1)
выдает следующее исключение:
Эта операция не поддерживается для относительного URI.
Когда я запускаю это клиентское приложение на своем компьютере для разработки с точно такой же конфигурацией, за исключением того, что я удаляю proxyAddress="10.20.30.40:8080"
С привязок операция работает без проблем.
Теперь я действительно не знаю, какое указание адреса прокси-сервера может иметь отношение к абсолютным или относительным URI. Использование прокси-сервера или нет - единственное отличие, которое я вижу при запуске клиента в рабочей среде или на компьютере разработчика.
У кого-то есть идея, что это исключение может означать в этом контексте и как возможно решить проблему?
Заранее спасибо за помощь!
Редактировать:
На случай, если это важно: служба и клиент создаются с помощью WCF в .NET Framework 4.
1 ответ
10.20.30.40:8080
не является действительным URL Ты хочешь http://10.20.30.40:8080
,
Вот мой диагностический мыслительный процесс, на случай, если он кому-нибудь поможет:
- Исключения обычно не лгут. Обычно они имеют в виду именно то, что говорят. Хитрость заключается в том, чтобы понять, как они могут говорить правду.
- Исключение говорит: "Эта операция не поддерживается для относительного URI". Если это было правдой, то это означало, что выполнялась операция, ей давался относительный URL, но он не поддерживает относительные URI.
- Затем ОП сказал, что когда он запускает приложение "за исключением того, что я удаляю proxyAddress="10.20.30.40:8080"из привязок".
Передо мной был относительный URI. Когда он удалил ее, "операция" сработала, поэтому я понял, что это был относительный URI, предоставленный "операции", которая их не поддерживает.
Вам не обязательно быть Шерлоком Холмсом, чтобы решить это. Ключ был в состоянии сразу увидеть, что не было scheme://
перед URI, что делает его относительным.