Ошибка HTTP Bad Request при запросе контракта на обслуживание WCF - PullRequest
12 голосов
/ 27 ноября 2008

У меня есть служба WCF со следующей конфигурацией:

<system.serviceModel>
    <behaviors>
        <serviceBehaviors>
            <behavior name="MetadataEnabled">
                <serviceDebug includeExceptionDetailInFaults="true" />
                <serviceMetadata httpGetEnabled="true" />
            </behavior>
        </serviceBehaviors>
     </behaviors>
      <services>
          <service behaviorConfiguration="MetadataEnabled" name="MyNamespace.MyService">
              <endpoint name="BasicHttp"
                        address=""
                        binding="basicHttpBinding"
                        contract="MyNamespace.IMyServiceContract" />
              <endpoint name="MetadataHttp"
                        address="contract"
                        binding="mexHttpBinding" 
                        contract="IMetadataExchange" />
              <host>
                  <baseAddresses>
                      <add baseAddress="http://localhost/myservice" />
                  </baseAddresses>
              </host>
          </service>
    </services>
</system.serviceModel>

При размещении службы в процессе WcfSvcHost.exe , если перейти по URL-адресу:

http://localhost/myservice/contract

при наличии метаданных службы я получаю ошибку HTTP 400 Bad * .

Изучив журналы WCF, я обнаружил, что с сообщением выдается исключение System.Xml.XmlException : " Тело сообщения не может быть прочитано, поскольку оно пустое. "
Вот выдержка из файла журнала:

<Exception>
<ExceptionType>
System.ServiceModel.ProtocolException, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
</ExceptionType>
<Message>There is a problem with the XML that was received from the network. See inner exception for more details.</Message>
<StackTrace>
at System.ServiceModel.Channels.HttpRequestContext.CreateMessage()
at System.ServiceModel.Channels.HttpChannelListener.HttpContextReceived(HttpRequestContext context, ItemDequeuedCallback callback)
at System.ServiceModel.Channels.SharedHttpTransportManager.OnGetContextCore(IAsyncResult result)
at System.ServiceModel.Channels.SharedHttpTransportManager.OnGetContext(IAsyncResult result)
at System.ServiceModel.Diagnostics.Utility.AsyncThunk.UnhandledExceptionFrame(IAsyncResult result)
at System.Net.LazyAsyncResult.Complete(IntPtr userToken)
at System.Net.LazyAsyncResult.ProtectedInvokeCallback(Object result, IntPtr userToken)
at System.Net.ListenerAsyncResult.WaitCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped)
at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)
</StackTrace>
<InnerException>
<ExceptionType>System.Xml.XmlException, System.Xml, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</ExceptionType>
<Message>The body of the message cannot be read because it is empty.</Message>
<StackTrace>
at System.ServiceModel.Channels.HttpRequestContext.CreateMessage()
at System.ServiceModel.Channels.HttpChannelListener.HttpContextReceived(HttpRequestContext context, ItemDequeuedCallback callback)
at System.ServiceModel.Channels.SharedHttpTransportManager.OnGetContextCore(IAsyncResult result)
at System.ServiceModel.Channels.SharedHttpTransportManager.OnGetContext(IAsyncResult result)
at System.ServiceModel.Diagnostics.Utility.AsyncThunk.UnhandledExceptionFrame(IAsyncResult result)
at System.Net.LazyAsyncResult.Complete(IntPtr userToken)
at System.Net.LazyAsyncResult.ProtectedInvokeCallback(Object result, IntPtr userToken)
at System.Net.ListenerAsyncResult.WaitCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped)
at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)
</StackTrace>
</InnerException>
</Exception>

Если вместо этого перейти к URL-адресу:

http://localhost/myservice?wsdl

все работает отлично, и я получаю контракт WSDL. На этом этапе я также могу полностью удалить конечную точку метаданных "MetadataHttp" , и это не будет иметь никакого значения.

Я использую .NET 3.5 SP1. У кого-нибудь есть представление о том, что здесь может быть не так?

Ответы [ 5 ]

12 голосов
/ 27 ноября 2008

Кажется, я выяснил, в чем проблема.

Если я перейду к URL:

http://localhost/myservice/contract

с приложением WcfTestClient Я могу успешно получить метаданные службы.
Так что ошибка действительно возникает, только когда я запрашиваю URL через веб-браузер.

Ошибка HTTP Bad Request происходит из-за того, что браузер выдает запрос HTTP GET, когда содержимое сообщения находится в заголовках HTTP, а тело пусто.
Это именно на что жалуется WCF mexHttpBinding !

Чтобы получить контракт на обслуживание через веб-браузер, вам необходимо явно включить его в поведении сервиса:

<serviceBehaviors>
    <behavior name="MetadataEnabled">
        <serviceMetadata httpGetEnabled="true" />
    </behavior>
</serviceBehaviors>

URL для запроса становится затем:

http://localhost/myservice?wsdl

Итак, оказалось, что я слишком быстро написал этот вопрос. Однако я все равно сохраню это для справки.

4 голосов
/ 10 ноября 2010

Как правило, это проблема с размером конверта SOAP. Проверьте свою конфигурацию привязки, чтобы изменить MaxBufferPoolSize, MaxReceivedMessageSize, чтобы разрешить огромное содержимое. Помните, что вы должны изменить как на стороне клиента, так и на стороне сервера.

Другой проблемой является MessageEnconding (еще один параметр привязки), убедитесь, что на стороне клиента и сервера используется одинаковая кодировка.

Наконец, проверьте параметры свойств квот Reader.

3 голосов
/ 18 марта 2010

Мне удалось устранить проблему «400 неверных запросов», переключив мою службу WCF с запуска Visual Studio Development Server на использование локального веб-сервера IIS (щелкните правой кнопкой мыши по проекту -> свойства -> вкладка «Интернет» - -> переключатель под «Серверы»). Я надеюсь, что это поможет кому-то там, потому что мне понадобилось два дня, чтобы понять это.

2 голосов
/ 26 марта 2014

У меня были проблемы с HTTP 400 при использовании HTTPS mex URL из SvcUtil, eventhough httpsGetEnabled было установлено на true. Сообщение об ошибке было очень далеко от того, что действительно было проблемой, поэтому я публикую здесь на случай, если кто-то еще наткнется на ту же проблему.

У меня был самозаверяющий сертификат CA (TestRootCA), который выдал сертификат сервера (localhost). На клиенте я импортировал файл TestRootCA CER, но не импортировал CRL (список отзыва сертификатов). Кажется, что когда вы используете самозаверяющий центр сертификации, вы должны также импортировать список отзыва сертификатов, в противном случае проверка подлинности сервера не может быть выполнена странным образом, и ни один из них не указывает на реальную проблему. Хуже всего то, что сбой происходит во время SSL-квитирования, за до запроса даже доходит до вашего сервиса, поэтому вы не увидите ошибок в журналах трассировки WCF.

2 голосов
/ 23 марта 2011

Если вы не уверены, почему ваш код WCF вызывает ошибку, я настоятельно рекомендую MS Service Trace Viewer. Это очень полезно при выявлении таких вопросов, как связь и транспорт. Взгляните на эту статью C # Corner для более подробной информации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...