如果WebClient返回异常,WCF服务将超时



我有一个WCF服务作为代理,它调用WebClient来返回字符串。WebClient正在查询通过https发送用户名和密码的Token服务。如果用户名和密码正确,该服务可以正常工作,但如果用户名和口令无效,WebClient会抛出一个异常(403 Forbidden),这是预期的,并在下面的代码中进行处理。然而,WCF服务随后继续挂起,直到超时,我不知道为什么。

Public Function GetToken(un As String, pw As String, ref As String) As TokenResult Implements IAGSAuthentication.GetToken
        Dim Token As String
        Dim TokenURL As String = String.Format("https://server/arcgisserver/tokens?request=getToken&username={0}&password={1}&timeout={2}", un, pw, Timeout)
        Dim tokenResult As TokenResult = New TokenResult
        If TokenService.IsBusy = False Then
            Try
                Token = TokenService.DownloadString(New Uri(TokenURL))
                tokenResult.Token = Token
                Return tokenResult
                Exit Function
            Catch ANEx As ArgumentNullException
                TokenService.Dispose()
                tokenResult.TokenException = ANEx
                Return tokenResult
                Exit Function
            Catch WEx As WebException
                TokenService.Dispose()
                tokenResult.TokenException = WEx
                Return tokenResult
                Exit Function
            Catch CEx As CommunicationException
                TokenService.Dispose()
                tokenResult.TokenException = CEx
                Return tokenResult
                Exit Function
            Catch Ex As Exception
                TokenService.Dispose()
                tokenResult.TokenException = Ex
                Return tokenResult
                Exit Function
            End Try
        End If
        Return tokenResult
    End Function

我还应该补充一点,当im调试WCF引用文件时,它显示了一个自动填充的客户端方法的异常。

Public Function EndGetToken(ByVal result As System.IAsyncResult) As AuthServiceRef.TokenResult Implements AuthServiceRef.AuthService.EndGetToken
                Dim _args((0) - 1) As Object
                Dim _result As AuthServiceRef.TokenResult = CType(MyBase.EndInvoke("GetToken", _args, result),AuthServiceRef.TokenResult)
                Return _result
            End Function

我认为,通过在WCF服务中处理异常并在自定义类中返回异常,我可以将异常推送给用户,而不会出现运行时问题。以下是客户端捕获的异常:

System.ServiceModel.CommunicationException was unhandled by user code

消息=远程服务器返回错误:NotFound。StackTrace:在System.ServiceModel.AsyncResult.End[TAsyncResult](IAsyncResult结果)在System.ServiceModel.Channels.ServiceChannel.EndCall(字符串操作,对象[]输出,IAsyncResult结果)在System.ServiceModel.ClientBase 1.ChannelBase 1.EndInvoke(String methodName,Object[]args,IAsyncResult result)位于MatrixWebMap.AuthServiceRef.AuthServiceClient.AuthServiceClient通道.EndGetToken(IAsyncResult结果)位于MatrixWebMap.AuthServiceRef.AuthServiceClient.AuthServiceRef_AuthService_EndGetToken(IAsyncResult结果)位于MatrixWebMap.AuthServiceRef.AuthServiceClient.OnEndGetToken(IAsyncResult结果)位于System.ServiceModel.ClientBase`1.OnAsyncCallCompleted(IAsyncResult结果)InnerException:System.Net.WebException消息=远程服务器返回错误:NotFound。StackTrace:位于System.Net.Browser.AncHelper.BeginOnUI(SendOrPostCallback beginMethod,对象状态)位于System.Net.Browser.BrowserHttpWebRequest.EndGetResponse(IAsyncResult-asyncResult)位于System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChanelAsyncRequest.CompleteGetResponse(IAsyncResult结果)InnerException:System.Net.WebException消息=远程服务器返回错误:NotFound。StackTrace:位于System.Net.Browser.BrowserHttpWebRequest.InternalEndGetResponse(IAsyncResult-asyncResult)位于System.Net.Browser.BrowserHttpWebRequest。<>c_DisplayClassa.b_9(对象发送状态)位于System.Net.Browser.AncHelper。<>c_DisplayClass4.b_0(对象发送状态)内部异常:

因此,从我将异常添加到TokenResult类并返回它时收集到的信息来看,WCF响应的异常属性有问题。解决方法是在响应之前处理异常,并使TokenException成为在返回结果之前创建的字符串。

因此,对于一个"403 Forbidden"web异常,我只是构造了一个字符串并返回"您输入的信息与我们的记录不匹配。请再试一次。"这是一项肮脏的工作,但它完全适合我在这里尝试做的事情。

            Try
                Token = TokenService.DownloadString(New Uri(TokenURL))
                tokenResult.Token = Token
                Return tokenResult
                Exit Function
            Catch ANEx As ArgumentNullException                
                tokenResult.TokenException = ANEx.Message
                Return tokenResult
                Exit Function
            Catch WEx As WebException                   
                If WEx.Status = WebExceptionStatus.ProtocolError Then
                    tokenResult.TokenException = "The information you have entered does not match our records. Please try again."
                Else
                    tokenResult.TokenException = WEx.Message
                End If
                Return tokenResult
                Exit Function
            Catch CEx As CommunicationException      
                tokenResult.TokenException = CEx.Message
                Return tokenResult
                Exit Function
            Catch Ex As Exception                    
                tokenResult.TokenException = Ex.Message
                Return tokenResult
                Exit Function
            End Try

最新更新