从ASP.NET客户端进行WCF故障排除 - 帮助!

时间:2009-08-20 17:37:08

标签: c# wcf

我正在尝试从ASP.NET应用程序中调用我的服务中的方法,如下所示。

public bool ValidateUser(string username, string password)
{
    try
    {
        // String CurrentLoggedInWindowsUserName = WindowsIdentity.GetCurrent().Name;
        // //primary identity of the call
        // String CurrentServiceSecurityContextPrimaryIdentityName = 
        //   ServiceSecurityContext.Current.PrimaryIdentity.Name;
        //
    }
    catch (Exception ex)
    {
        FaultExceptionFactory fct = new FaultExceptionFactory();
        throw new FaultException<CustomFaultException>(fct.CreateFaultException(ex));
    }
    return false;
}

我的服务的客户端配置如下

<binding name="WSHttpBinding_IMembershipService" closeTimeout="00:01:00"
     openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
     bypassProxyOnLocal="false" transactionFlow="false"
     hostNameComparisonMode="StrongWildcard"
     maxBufferPoolSize="524288" maxReceivedMessageSize="65536" messageEncoding="Text"
     textEncoding="utf-8" useDefaultWebProxy="false" allowCookies="false">
    <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
       maxBytesPerRead="4096" maxNameTableCharCount="16384" />
    <reliableSession ordered="true" inactivityTimeout="00:10:00"
       enabled="false" />
    <security mode="Message">
        <transport clientCredentialType="Windows" proxyCredentialType="None"
         realm="" />
        <message clientCredentialType="Windows" negotiateServiceCredential="true"
         algorithmSuite="Default" establishSecurityContext="true" />
    </security>
</binding>

我一直在问的问题是我打电话的时候;我收到以下异常消息。

Server Error in '/' Application. 

The communication object, System.ServiceModel.Channels.ServiceChannel, 
cannot be used for communication because it is in the Faulted state. 
Description: An unhandled exception occurred during the execution of 
the current web request. Please review the stack trace for more 
information about the error and where it originated in the code. 

Exception Details: System.ServiceModel.CommunicationObjectFaultedException: 
The communication object, System.ServiceModel.Channels.ServiceChannel, 
cannot be used for communication because it is in the Faulted state.

Stack Trace: 

[CommunicationObjectFaultedException: The communication object, 
  System.ServiceModel.Channels.ServiceChannel, cannot be used for 
  communication because it is in the Faulted state.]
   System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, 
         IMessage retMsg) +7596735
   System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, 
         Int32 type) +275
   System.ServiceModel.ICommunicationObject.Close(TimeSpan timeout) +0

   System.ServiceModel.ClientBase`1.System.ServiceModel.ICommunicationObject.
         Close(TimeSpan timeout) +142
   System.ServiceModel.ClientBase`1.Close() +38
   System.ServiceModel.ClientBase`1.System.IDisposable.Dispose() +4
   Controls.Membership.accountLogin.ValidateUserCredentials(String UserName, 
            String Password) in C:\ Petition.WebClient\Controls\
                               Membership\accountLogin.ascx.cs:49
   Controls.Membership.accountLogin.Login1_Authenticate(Object sender, 
             AuthenticateEventArgs e) in C:\ WebClient\ Controls\Membership
                                      \accountLogin.ascx.cs:55

我不完全确定为什么我会继续这样做。以防万一,这是我从客户端调用我的服务的方式

private bool ValidateUserCredentials(string UserName, string Password)
{
    bool boolReturnValue = false;

    using(Members.MembershipServiceClient client =
        new Controls.Members.MembershipServiceClient())
    {
        try
        {
            boolReturnValue = client.ValidateUser(UserName, Password);
        }
        catch (FaultException<CustomFaultException> ex)
        {
          throw ex;
        }
    }

    return boolReturnValue;
} 

任何人都知道在这种情况下我需要做什么?

4 个答案:

答案 0 :(得分:5)

WCF客户端代理是.NET中的两个位置之一,您不应该在实现using的类的实例周围实现IDisposable块。请参阅Indisposable: WCF Gotcha #1

OBTW,摆脱客户端呼叫周围的try / catch块。除非你能以某种方式“处理”它,否则不要捕获异常,再扔掉它不会“处理”它。

答案 1 :(得分:4)

我确信您可能已经意识到这一点,但如果没有,在这些情况下,WCF跟踪可能会有所帮助。

特别是在代码已发布,正在生产且无法更新的情况下,但服务器端会抛出意外错误,例如:你没有在合同中指明的。

同样能够查看消息有效负载是非常宝贵的。

要获取跟踪,请在app.config中打开WCF跟踪或等效。

这取决于您认为错误最有可能发生的位置(客户端或服务器,或两者),以及您可能希望打开跟踪的位置。

然后使用Service Trace Viewer工具打开它生成的XML日志文件。

在我的机器上,它位于C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\bin\SvcTraceViewer.exe,但您的位置可能略有不同。

有关详细信息,请参阅MSDN上的Service Trace Viewer页面。

答案 2 :(得分:1)

嗯,使用您当前的客户端设置,您希望对邮件进行加密和签名,并将您的Windows凭据作为身份发送。

如果尝试处理此请求的远程服务器在同一LAN上,或者无法访问同一个Active Directory来验证这些用户凭据,则会收到此消息。

服务器和客户端上的安全设置必须匹配 - 例如如果你的服务器有类似的东西

<security mode="None">

然后你必须在客户端上拥有相同的设置。如果您的服务器无法验证Windows凭据,请不要使用它们。要么根本不使用安全性(不建议除了开发/测试),要么允许匿名调用者(但仍然使用例如消息安全性),或者你必须定义一个调用者可以在其中进行身份验证的自定义机制。

WCF中的安全性是一个广阔的领域:-)以下是一些可能有助于掌握主题的链接:

对于WCF中相关安全性的一个非常完整但几乎令人生畏的概述,CodePlex上有WCF Security Guidance

希望这有助于您入门!

马克

答案 3 :(得分:0)

消息:“CommunicationObjectFaultedException”通常发生在您不将Dispose应用于使用Using块的通道时,因此您只需要添加一个语句Abort,如下所示:

catch (Exception ex) 
{ 
  client.Abort(); 
} 

我希望这可以帮到你。