Устранение неполадок WCF из клиента ASP.NET - Помощь! - PullRequest
2 голосов
/ 20 августа 2009

Я пытаюсь вызвать метод в моем сервисе, как показано ниже, из приложения 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 ]

5 голосов
/ 20 августа 2009
Клиентские прокси

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

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

4 голосов
/ 21 августа 2009

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

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

Также возможность просмотра полезных данных сообщения может быть неоценимой.

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

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

Затем с помощью инструмента Service Trace Viewer откройте создаваемые им файлы журнала XML.

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

Дополнительную информацию см. На странице Просмотр трассировки служб в MSDN.

1 голос
/ 21 августа 2009

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

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

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

<security mode="None">

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

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

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

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

Марк

0 голосов
/ 15 июня 2010

Сообщение: «CommunicationObjectFaptedException» обычно возникает, когда вы не применяете Dispose к каналам, работающим с блоком Using, поэтому вам нужно только добавить оператор Abort следующим образом:

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

Надеюсь, это поможет Вам.

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