2009-08-20 2 views
2

Я пытаюсь вызвать метод в моем сервисе, который приведен ниже, из приложения ASP.NET.Устранение неполадок 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; 
} 

Кто-нибудь есть какие-либо идеи, что мне нужно делать в этом случае?

ответ

5

Прокси-серверы WCF являются одним из двух мест в .NET, где вы не должны реализовывать блок using вокруг экземпляра класса, который реализует IDisposable. См. Indisposable: WCF Gotcha #1.

OBTW, избавиться от блока try/catch вокруг вашего вызова в клиенте. Не поймайте исключение, если вы не сможете «обработать» его каким-то образом, а выбросить его снова не «обрабатываете» его.

+1

Ссылка выше кажется нарушенной. Вот альтернатива: http://web.archive.org/web/20080803051143/www.iserviceoriented.com/blog/post/Indisposable+-+WCF+Gotcha+1.aspx – Kit

1

Ну, с вашей текущей настройкой клиента вы ожидаете зашифровать и подписать ваши сообщения и отправить свои учетные данные Windows как личность.

Если удаленный сервер, который пытается обработать этот запрос, составляет NOT в той же локальной сети или не имеет доступа к тому же Active Directory для проверки этих учетных данных пользователя, вы получите это сообщение.

Параметры безопасности на сервере и клиенте должны совпадать - например, если у вашего сервера есть что-то вроде

<security mode="None"> 

тогда вы должны иметь одинаковые настройки и на клиенте. Если ваш сервер не может проверить учетные данные Windows, не используйте их. Либо не используйте никакой безопасности (не рекомендуется, за исключением разработки/тестирования), либо разрешите анонимные вызывающие абоненты (но все равно использовать, например, безопасность сообщений), или же вам нужно определить настраиваемый механизм, в котором вызывающий может аутентифицировать себя.

безопасности в WCF огромное поле :-) Вот некоторые ссылки, которые могут помочь получить власть на тему:

  • WCF SEcurity Scenarios основан на отлично «Программирование WCF» Юваль Лоуи в книге
  • Juval Lowy's Declarate WCF Security статьи на как обращаться безопасность с помощью нескольких атрибутов

и для действительно полного, но и почти пугающего обзора всех вещей, связанной с безопасностью в WCF, есть WCF Security Guidance на CodePlex.

Надеюсь, это поможет вам начать работу!

Марк

4

Я уверен, что вы, вероятно, знают об этом, но если нет, то трассировка WCF может оказаться полезным в таких ситуациях.

Особенно в сценариях, в которых код отправлен, находится в производстве и не обновляется, но на стороне сервера возникает непредвиденная ошибка, например. тот, который вы не указали в контракте.

Кроме того, возможность просмотра сообщений может быть неоценимой.

Чтобы получить трассировку, включите трассировку WCF в файле app.config или аналогичном.

Это зависит от того, где, по вашему мнению, может произойти ошибка (клиент или сервер или и то и другое) относительно того, где вы, вероятно, хотите включить трассировку.

Затем с помощью инструмента просмотра служебных трасс откроется файл журнала XML, который он создает.

На моей машине это в C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\bin\SvcTraceViewer.exe, но ваше местоположение, вероятно, немного отличается.

Дополнительную информацию см. На странице Service Trace Viewer на MSDN.

0

сообщение: «CommunicationObjectFaultedException» обычно происходит, когда вы не применяются Dispose к каналам, работающих с помощью блока, поэтому Вам нужно только добавить заявление Прервать так:

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

Я надеюсь, что это может помочь тебе.

Смежные вопросы