Не было ни одного канала, который мог бы принять сообщение с действием
Когда я получаю доступ к своему веб-сервису через WcfTestClient, он возвращает мне несколько сотен результатов за несколько секунд, поэтому мой веб-сервис работает нормально.
Теперь, когда я пытаюсь получить к нему доступ через приложение, оно вызывает у меня всевозможные ошибки.
Мой веб-сервис находится на веб-сайте, размещенном в Visual Studio, я обращаюсь к нему на локальном хосте, и когда я перехожу к конечной точке, он не выдает ошибку (только сообщение о том, как создать прокси-класс).
У меня уже есть другое приложение webservice +, которое отлично работает благодаря добрым джентльменам: веб-сервис WCF - его нельзя использовать на производстве. Очевидно, я скопировал и вставил файлы конфигурации, но не повезло.
Прокси-класс генерируется автоматически Visual Studio через "Добавить ссылку на веб-сервис".
У меня есть точно описанные там симптомы: http://webservices20.blogspot.com/2009/04/which-binding-to-use-wshttpbinding-or.html но этот сайт не предлагает конкретных решений, поэтому он не очень помогает мне.
Интерфейс службы IPushMail (в DLL):
Imports System.ServiceModel
Imports System.Collections.Generic
Imports System.ServiceModel.Web
<ServiceContract()> _
Public Interface IPushMail
<OperationContract()> _
<WebGet(UriTemplate:="GetEmails")> _
Function GetEmails() As List(Of CMS.Mail.MailSerialiserPushMail)
<OperationContract()> _
<WebGet(UriTemplate:="IncrementerNumero")> _
Function Incrementer() As Boolean
End Interface
Класс веб-службы PushMail (в папке App_Code сайта):
Imports System.Collections.Generic
Public Class PushMail
Implements IPushMail
Public Function GetEmails() As List(Of CMS.Mail.MailSerialiserPushMail) Implements IPushMail.GetEmails
Dim mails As New List(Of CMS.Mail.MailSerialiserPushMail)
' get mails
Return mails
End Function
Public Function Incrementer() As Boolean Implements IPushMail.Incrementer
' update record
Return True
End Function
End Class
Приложение PushMail:
Imports System.Collections.Generic
Imports System.Text
Module PushMail
Sub Main()
Dim pmClient As New PushMailService.PushMailClient()
Dim mails As List(Of PushMailService.MailSerialiserPushMail) = pmClient.GetEmails()
For Each m In mails
' do stuff
Next
If (pmClient.Incrementer()) Then
Console.WriteLine("FINI")
End If
pmClient.Close()
End Sub
End Module
Web.Config:
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="wsHttpBinding" allowCookies="true" maxReceivedMessageSize="200000000" maxBufferPoolSize="200000000" useDefaultWebProxy="true">
<security mode="Transport">
<transport clientCredentialType="Windows" proxyCredentialType="None" realm=""/>
</security>
</binding>
<binding name="NoSecurityBinding" allowCookies="true" maxReceivedMessageSize="200000000" maxBufferPoolSize="200000000" useDefaultWebProxy="true">
<security mode="Message">
<transport clientCredentialType="Windows" proxyCredentialType="None" realm="" />
<message clientCredentialType="Windows" negotiateServiceCredential="true" establishSecurityContext="true" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<!-- here are a few other behaviors -->
<behavior name="PushMailBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true" httpHelpPageEnabled="true"/>
<serviceCredentials>
<windowsAuthentication allowAnonymousLogons="true" />
</serviceCredentials>
<dataContractSerializer maxItemsInObjectGraph="2147483647" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<!-- here are a few other services -->
<service behaviorConfiguration="PushMailBehavior" name="PushMail">
<endpoint address="" binding="wsHttpBinding" contract="IPushMail" bindingConfiguration="NoSecurityBinding">
<identity>
<dns value="localhost"/>
<userPrincipalName value=".\NetworkService" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
</system.serviceModel>
App.Config:
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IPushMail" closeTimeout="20:00:00"
openTimeout="20:00:00" receiveTimeout="20:00:00" sendTimeout="20:00:00"
bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="200000000" maxReceivedMessageSize="200000000"
messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
allowCookies="false">
<readerQuotas maxDepth="32" maxStringContentLength="200000000"
maxArrayLength="200000000" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="20:00:00"
enabled="false" />
<security mode="Message">
<transport clientCredentialType="Windows" proxyCredentialType="None"
realm="" />
<message clientCredentialType="Windows" negotiateServiceCredential="true"
algorithmSuite="Default" establishSecurityContext="false" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:60308/WebServices/PushMail.svc"
behaviorConfiguration="PushMailBehavior" binding="wsHttpBinding"
bindingConfiguration="WSHttpBinding_IPushMail" contract="PushMailService.IPushMail"
name="WSHttpBinding_IPushMail">
<identity>
<userPrincipalName value=".\NetworkService" />
<dns value="localhost" />
</identity>
</endpoint>
</client>
<behaviors>
<endpointBehaviors>
<behavior name="PushMailBehavior">
<dataContractSerializer maxItemsInObjectGraph="2147483647" />
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
И вот ошибки, которые я получаю:
Приложение генерирует общее сообщение: "Необеспеченная ошибка или неправильно защищенная ошибка была получена от другой стороны. См. Внутреннее исключение ошибки для кода ошибки и детализации". InnerException не очень помогает: "Сообщение не может быть обработано. Это, скорее всего, потому, что действие xxx неверно, или потому что сообщение содержит недопустимый токен контекста безопасности с истекшим сроком действия или из-за несоответствия между привязками".
Журнал трассировки немного подробнее. Он начинается с того, что выдает мне два похожих предупреждения: "Указанный домен либо не существует, либо с ним нельзя связаться".
<E2ETraceEvent xmlns="http://schemas.microsoft.com/2004/06/E2ETraceEvent">
<System xmlns="http://schemas.microsoft.com/2004/06/windows/eventlog/system">
<EventID>131076</EventID>
<Type>3</Type>
<SubType Name="Warning">0</SubType>
<Level>4</Level>
<TimeCreated SystemTime="2012-01-04T10:05:57.8896060Z" />
<Source Name="System.ServiceModel" />
<Correlation ActivityID="{7d9b9578-467c-4949-ad5e-380d4ae6a0b0}" />
<Execution ProcessName="WebDev.WebServer" ProcessID="17264" ThreadID="4" />
<Channel />
<Computer>PC-THOMAS-WIN7</Computer>
</System>
<ApplicationData>
<TraceData>
<DataItem>
<TraceRecord xmlns="http://schemas.microsoft.com/2004/10/E2ETraceEvent/TraceRecord" Severity="Warning">
<TraceIdentifier>http://msdn.microsoft.com/fr-FR/library/System.ServiceModel.Diagnostics.TraceHandledException.aspx</TraceIdentifier>
<Description>Traitement d’une exception.</Description>
<AppDomain>cf2e76e7-10-129701451365074680</AppDomain>
<Exception>
<ExceptionType>System.ComponentModel.Win32Exception, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</ExceptionType>
<Message>Le domaine spécifié n’existe pas ou n’a pas pu être contacté</Message>
<StackTrace>
à System.ServiceModel.UpnEndpointIdentity.GetUpnFromDownlevelName(String downlevelName)
à System.ServiceModel.UpnEndpointIdentity.GetUpnFromWindowsIdentity(WindowsIdentity windowsIdentity)
</StackTrace>
<ExceptionString>System.ComponentModel.Win32Exception: Le domaine spécifié n’existe pas ou n’a pas pu être contacté
à System.ServiceModel.UpnEndpointIdentity.GetUpnFromDownlevelName(String downlevelName)
à System.ServiceModel.UpnEndpointIdentity.GetUpnFromWindowsIdentity(WindowsIdentity windowsIdentity)</ExceptionString>
<NativeErrorCode>54B</NativeErrorCode>
</Exception>
</TraceRecord>
</DataItem>
</TraceData>
</ApplicationData>
</E2ETraceEvent>
Чуть дальше внизу отображается ошибка: "Не было канала, который мог бы принять сообщение с действием xxx".
<E2ETraceEvent xmlns="http://schemas.microsoft.com/2004/06/E2ETraceEvent">
<System xmlns="http://schemas.microsoft.com/2004/06/windows/eventlog/system">
<EventID>131075</EventID>
<Type>3</Type>
<SubType Name="Error">0</SubType>
<Level>2</Level>
<TimeCreated SystemTime="2012-01-04T10:05:57.9286099Z" />
<Source Name="System.ServiceModel" />
<Correlation ActivityID="{22dc2d84-586b-4221-aae4-d529e4b7560a}" />
<Execution ProcessName="WebDev.WebServer" ProcessID="17264" ThreadID="4" />
<Channel />
<Computer>PC-THOMAS-WIN7</Computer>
</System>
<ApplicationData>
<TraceData>
<DataItem>
<TraceRecord xmlns="http://schemas.microsoft.com/2004/10/E2ETraceEvent/TraceRecord" Severity="Error">
<TraceIdentifier>http://msdn.microsoft.com/fr-FR/library/System.ServiceModel.Diagnostics.ThrowingException.aspx</TraceIdentifier>
<Description>Génération d’une exception.</Description>
<AppDomain>cf2e76e7-10-129701451365074680</AppDomain>
<Exception>
<ExceptionType>System.ServiceModel.EndpointNotFoundException, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</ExceptionType>
<Message>Aucun canal ne pouvait accepter le message avec l’action « http://tempuri.org/IPushMail/GetEmails ».</Message>
<StackTrace>
à System.ServiceModel.Dispatcher.ErrorBehavior.ThrowAndCatch(Exception e, Message message)
à System.ServiceModel.Channels.DatagramChannelDemuxer`2.ProcessItem(TInnerItem item)
à System.ServiceModel.Channels.DatagramChannelDemuxer`2.HandleReceiveResult(IAsyncResult result)
à System.ServiceModel.Channels.DatagramChannelDemuxer`2.OnReceiveCompleteStatic(IAsyncResult result)
à System.ServiceModel.Diagnostics.Utility.AsyncThunk.UnhandledExceptionFrame(IAsyncResult result)
à System.ServiceModel.AsyncResult.Complete(Boolean completedSynchronously)
à System.ServiceModel.Channels.ReplyChannel.HelpReceiveRequestAsyncResult.OnReceiveRequest(IAsyncResult result)
à System.ServiceModel.Diagnostics.Utility.AsyncThunk.UnhandledExceptionFrame(IAsyncResult result)
à System.ServiceModel.AsyncResult.Complete(Boolean completedSynchronously)
à System.ServiceModel.Channels.InputQueue`1.AsyncQueueReader.Set(Item item)
à System.ServiceModel.Channels.InputQueue`1.EnqueueAndDispatch(Item item, Boolean canDispatchOnThisThread)
à System.ServiceModel.Channels.InputQueue`1.EnqueueAndDispatch(T item, ItemDequeuedCallback dequeuedCallback, Boolean canDispatchOnThisThread)
à System.ServiceModel.Channels.InputQueueChannel`1.EnqueueAndDispatch(TDisposable item, ItemDequeuedCallback dequeuedCallback, Boolean canDispatchOnThisThread)
à System.ServiceModel.Channels.SingletonChannelAcceptor`3.Enqueue(QueueItemType item, ItemDequeuedCallback dequeuedCallback, Boolean canDispatchOnThisThread)
à System.ServiceModel.Channels.HttpChannelListener.HttpContextReceived(HttpRequestContext context, ItemDequeuedCallback callback)
à System.ServiceModel.Activation.HostedHttpTransportManager.HttpContextReceived(HostedHttpRequestAsyncResult result)
à System.ServiceModel.Activation.HostedHttpRequestAsyncResult.HandleRequest()
à System.ServiceModel.Activation.HostedHttpRequestAsyncResult.BeginRequest()
à System.ServiceModel.Activation.HostedHttpRequestAsyncResult.OnBeginRequest(Object state)
à System.ServiceModel.Channels.IOThreadScheduler.CriticalHelper.WorkItem.Invoke2()
à System.ServiceModel.Channels.IOThreadScheduler.CriticalHelper.WorkItem.Invoke()
à System.ServiceModel.Channels.IOThreadScheduler.CriticalHelper.ProcessCallbacks()
à System.ServiceModel.Channels.IOThreadScheduler.CriticalHelper.CompletionCallback(Object state)
à System.ServiceModel.Channels.IOThreadScheduler.CriticalHelper.ScheduledOverlapped.IOCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped)
à System.ServiceModel.Diagnostics.Utility.IOCompletionThunk.UnhandledExceptionFrame(UInt32 error, UInt32 bytesRead, NativeOverlapped* nativeOverlapped)
à System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)
</StackTrace>
<ExceptionString>System.ServiceModel.EndpointNotFoundException: Aucun canal ne pouvait accepter le message avec l’action « http://tempuri.org/IPushMail/GetEmails ».</ExceptionString>
</Exception>
</TraceRecord>
</DataItem>
</TraceData>
</ApplicationData>
</E2ETraceEvent>
Похоже, что с доменом (localhost) невозможно связаться, но я могу получить к нему доступ с помощью WcfTestClient! Я действительно не понимаю...
Спасибо за вашу помощь...
1 ответ
ОК, я нашел решение... Был establishSecurityContext="true"
в файле web.config и establishSecurityContext="false"
в app.config. Я установил его в true в app.config, и теперь он работает...