EndpointNotFoundException при вызове операции запуска службы RESTful WCF

У меня действительно странная проблема с одной из моих служб WCF. Я почти уверен, что у большинства людей, которые экспериментировали со службами WCF, возникал EndpointNotFoundException, когда конечная точка была неправильно настроена в одном из их файлов конфигурации. Из класса EndpointNotFoundException в MSDN:

Исключение, которое выдается, когда удаленная конечная точка не может быть найдена или достигнута.

Далее продолжается:

Конечная точка может быть не найдена или недоступна, потому что удаленная конечная точка не работает, удаленная конечная точка недоступна или удаленная сеть недоступна.

Это не отражает мою ситуацию. Таким образом, кажется, что получение EndpointNotFoundException при работе с WCF не является чем-то необычным, но этот Exception не выдается при первой попытке доступа к службе... вместо этого он выдается только при попытке вызвать одну из операций сервиса:

using (ExportConfirmationServiceClient client = new ExportConfirmationServiceClient(
    "WebHttpBinding_IExportConfirmationService")) // <-- Exception is NOT thrown here
{
    ...
    component releaseConfirmation = DeserializeTestXmlFile(filePath);
    client.AddExportConfirmation("5051275066302", releaseConfirmation);
    // Exception is thrown on call to service operation on line above
    ...
}

Интересно, что сообщение Exception также включает в себя имя операции в указанном пути к файлу:

На http://domain/Folder/ServiceName.svc/OperationName не было прослушивающей конечной точки, которая могла бы принять сообщение. Это часто вызвано неверным адресом или действием SOAP. Дополнительные сведения см. в разделе InnerException, если он присутствует.

Внутренний Exception имеет следующее сообщение:

Удаленный сервер вернул ошибку: (404) Not Found.

Это особенно сбивает меня с толку, поскольку я могу успешно перейти к URL-адресу службы и увидеть страницу по умолчанию Вы создали службу:

введите здесь описание изображения

Кроме того, если я перейду к пути в сообщении Exception, я увижу на странице сообщение Конечная точка не найдена:

введите здесь описание изображения

Однако, если я перехожу на любую рабочую страницу одной из моих других работающих служб WCF, я получаю стандартную ошибку 400 Bad Request из браузера, даже если операция работает нормально. Так что мне кажется, что этот оригинальный EndpointNotFoundException может быть отвлекающим маневром... Хотя я действительно не уверен, так как не тратил много времени на работу с WCF.

Я покажу здесь свой web.config (на стороне сервера) на случай, если кому-то понадобится его увидеть:

<?xml version="1.0"?>
<configuration>    
    <system.web>
        <compilation debug="true" targetFramework="4.0" />
    </system.web>
    <system.serviceModel>
        <behaviors>
            <serviceBehaviors>
                <behavior name="Midas.WebConfirmations.ExportConfirmationServiceBehaviour">
                    <serviceMetadata httpGetEnabled="true" />
                    <serviceDebug includeExceptionDetailInFaults="false" />
                </behavior>
            </serviceBehaviors>
            <endpointBehaviors>
                <behavior name="webHttp">
                    <webHttp />
                </behavior>
            </endpointBehaviors>
        </behaviors>
        <serviceHostingEnvironment multipleSiteBindingsEnabled="false" />
        <services>
            <service name="Midas.WebConfirmations.ExportConfirmationService" behaviorConfiguration="Midas.WebConfirmations.ExportConfirmationServiceBehaviour">
                <endpoint address="" binding="webHttpBinding" contract="Midas.WebConfirmations.IExportConfirmationService" behaviorConfiguration="webHttp" />
                <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
            </service>
        </services>
    </system.serviceModel>
    <system.webServer>
        <modules runAllManagedModulesForAllRequests="true"/>
    </system.webServer>
</configuration>

Это клиент App.config (имейте в виду, что это ссылка на две службы WCF):

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <system.serviceModel>
        <bindings>
            <basicHttpBinding>
                <binding name="BasicHttpBinding_IDataService" 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="None">
                        <transport clientCredentialType="None" proxyCredentialType="None" realm="" />
                        <message clientCredentialType="UserName" algorithmSuite="Default" />
                    </security>
                </binding>
            </basicHttpBinding>
            <webHttpBinding>
                <binding name="WebHttpBinding_IExportConfirmationService" allowCookies="true" maxReceivedMessageSize="20000000" maxBufferSize="20000000" maxBufferPoolSize="20000000">
                    <readerQuotas maxDepth="32" maxArrayLength="200000000" maxStringContentLength="200000000"/>
                </binding>
            </webHttpBinding>
        </bindings>
        <behaviors>
            <serviceBehaviors>
                <behavior name="Midas.WebConfirmations.ExportConfirmationServiceBehaviour">
                    <serviceMetadata httpGetEnabled="true" />
                    <serviceDebug includeExceptionDetailInFaults="false" />
                </behavior>
            </serviceBehaviors>
            <endpointBehaviors>
                <behavior name="webEndpointBehavior">
                    <webHttp defaultBodyStyle="Wrapped" defaultOutgoingResponseFormat="Xml" helpEnabled="true"/>
                </behavior>
            </endpointBehaviors>
        </behaviors>
        <client>
            <endpoint address="http://devbucket.ministryofsound.mos.local/MidasWebServices/DataService.svc" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IDataService" contract="Midas.WebServiceClients.IDataService" name="BasicHttpBinding_IDataService" />
            <endpoint address="http://devbucket.ministryofsound.mos.local/MidasWebConfirmations/ExportConfirmationService.svc" binding="webHttpBinding" bindingConfiguration="WebHttpBinding_IExportConfirmationService" behaviorConfiguration="webEndpointBehavior" contract="IExportConfirmationService" name="WebHttpBinding_IExportConfirmationService" />
        </client>
    </system.serviceModel>
</configuration>

Поэтому, если кто-нибудь из великих умов, часто встречающихся с переполнением стека, может пролить свет на эту проблему для меня, я был бы очень признателен.


ОБНОВЛЕНИЕ >>>

В ответ на первые несколько комментариев я заподозрил, что проблема может быть вызвана Exception, выброшенным из кода на стороне сервера, поэтому я значительно упростил код операции... теперь все, что он делает, это то, но я все равно получаю то же самое. ошибка:

public void AddExportConfirmation(string upc, component ingestionFeedback)
{
    WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.OK;
}

Кроме того, я настроил трассировку, но она работала только на стороне клиента, поэтому сообщала мне только то, что я уже знала. Я посмотрю ссылку, которую вы предоставили @BigDaddy, на случай, если она покажет, как настроить трассировку на стороне сервера.

В ответ на Tewr я сгенерировал клиент службы, используя svcutil.exe, но я также попытался добавить ссылку на службу и позволить Visual Studio создать ссылку для меня... оба метода привели к одной и той же ошибке. Кроме того, я весь день обновлял ссылки на сервисы по мере внесения изменений. Настройка includeExceptionDetailInFaults="true" ничего не изменила, но я попробую добавить в сервис фиктивную операцию и попробовать просмотреть ее в браузере.


ОБНОВЛЕНИЕ 2 >>>

Хорошо, поэтому я добавил в службу простой метод получения и обновил все ссылки, как предложил @Tewr. Это только еще больше меня запутало... метод:

[XmlSerializerFormat()]
[OperationContract]
[WebGet()]
string GetString();

Реализация просто возвращает string, и я вижу это значение при доступе к сервису в веб-браузере: введите здесь описание изображения
Однако я по-прежнему получаю ту же ошибку в коде, даже при вызове этой той же новой операции... что это значит?


ОБНОВЛЕНИЕ 3 >>>

Приняв совет из комментариев, я снова настроил трассировку службы в службе... Я все еще не мог заставить работать ту, которая работает на сервере, но на клиенте она вывела файл трассировки. В этом файле я вижу InvalidOperationException со следующим сообщением:

Версия конверта 'EnvelopeNone (http://schemas.microsoft.com/ws/2005/05/envelope/none)' не поддерживает добавление заголовков сообщений.

Я просто изучаю это сейчас, поэтому, если вы знаете, что это за ошибка, пожалуйста, дайте мне знать.


person Sheridan    schedule 10.03.2014    source источник
comment
Если вы еще этого не сделали, настройте трассировку, чтобы увидеть, что происходит на самом деле. Следуйте этому: stackoverflow.com/questions/14217700/   -  person Big Daddy    schedule 10.03.2014
comment
Ваша теория отвлекающих маневров верна... Раньше я уже получал такое же исключение, но на самом деле это было необработанное исключение на стороне службы. Потребитель просто сдался и выбросил общее исключение. Отладьте другой конец.   -  person DonBoitnott    schedule 10.03.2014
comment
Похоже, вы используете сгенерированный файл serviceclient. Вы недавно меняли интерфейс службы и, возможно, забыли обновить ссылку на службу? Кроме того, я вижу, что вы используете привязку webHttp, это помогает вам проверять сопоставления только с помощью браузера. Создайте фиктивную функцию в своем сервисе [WebGet(UriTemplate = "Ping/")] bool Ping() { return true; } и попробуйте получить к ней доступ из браузера. Последний совет, includeExceptionDetailInFaults="true" может вам помочь.   -  person Tewr    schedule 10.03.2014
comment
@ Ваше ОБНОВЛЕНИЕ 1: включение трассировки должно вам помочь. Мне это помогло. И это может быть применено и на стороне сервера. Попробуйте изменить это: ‹trace autoflush=false /› и initializeData= D:\Log\Traces.svclog› Добавьте полный путь к initializeData.   -  person Faizan Mubasher    schedule 11.03.2014
comment
Поскольку ваша фиктивная функция работает, вероятность того, что ошибка будет на сервере, меньше. Ваш клиент app.config на первый взгляд выглядит нормально. В подобных случаях я запускал Fiddler и сравнивал заголовки/URL простого рабочего вызова браузера с заголовком из вашего .net-клиента. Поскольку ваше внутреннее исключение представляет собой ошибку 404 при использовании клиента .net, ваш клиент .net, вероятно, делает что-то странное с URL-адресом операции.   -  person Tewr    schedule 11.03.2014
comment
Попробуйте перезапустить все службы Net.TCP... это помогло решить мою проблему   -  person JoelFan    schedule 25.01.2016


Ответы (1)


Проблема с WCF заключается в том, что он такой сложный, Exceptions покрывает так много разных ошибок, а Exception сообщения такие расплывчатые. Из моего ограниченного опыта кажется, что сообщение об ошибке говорит одно, но часто оно будет полностью или частично нерелевантным для вашей реальной проблемы. Так что я в основном продолжал исправлять ошибки, которые открыли новые Exceptions (и я до сих пор еще не дошел до их конца!), но для целей этого вопроса есть есть ответ.

Итак, оказалось, что исходный EndpointNotFoundException был фактически брошен, потому что в реализации метода службы AddExportConfirmation был необработанный Exception. Как только я упростил код (как в обновлении первого вопроса), этот конкретный Exception ушел и был заменен следующим.

person Sheridan    schedule 12.03.2014