Устранение неполадок WCF из клиента ASP.NET - Помощь!

2

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

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

Теги:
wcf

4 ответа

5

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

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

4

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

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

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

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

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

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

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

Для получения дополнительной информации см. страницу Сервис-трассировщик на MSDN.

1

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

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

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

<security mode="None">

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

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

  • Сценарии WCF SEcurity, основанные на превосходной книге "Программирование WCF" от Juval Lowy.
  • Juval Lowy Declarate WCF Security статья о том, как обрабатывать безопасность всего несколькими атрибутами

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

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

Марк

0

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

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

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню