WCF 4.0, не могу вызвать службу - PullRequest
1 голос
/ 27 мая 2011

В решении я добавил «Сервисную библиотеку WCF». Нет проблем с методом по умолчанию. Я добавил один:

В интерфейсе:

[ServiceContract]
public interface ISecurityAccessService
{
    [OperationContract]
    string GetData(int value);

    [OperationContract]
    CompositeType GetDataUsingDataContract(CompositeType composite);

    [OperationContract]
    CompositeUser ListUser();

}

[DataContract]
public class CompositeUser
{
    List<User> _listUser = new List<User>();

    [DataMember]
    public List<User> ListUser
    {
        get { return _listUser; }
        set { _listUser = value; }
    }
}

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

public class SecurityAccessService : ISecurityAccessService
{
    public CompositeUser ListUser()
    {
        DataAccess.DataService service = new DataAccess.DataService();

        CompositeUser compositeUser = new CompositeUser();
        compositeUser.ListUser = service.ListUser();

        return compositeUser;
    }
}

Когда я выполняю и пытаюсь вызвать, я получаю это сообщение об ошибке: * Произошла ошибка при получении ответа HTTP на http://localhost:8732/Design_Time_Addresses/WcfServiceLibrary/ISecurityAccessService/. Это может быть связано с тем, что привязка конечной точки службы не использует протокол HTTP. Это также может быть связано с тем, что сервер прерывает контекст HTTP-запроса (возможно, из-за закрытия службы). Более подробную информацию смотрите в журналах сервера. *

App.config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.web>
    <compilation debug="true" />
  </system.web>
  <!-- When deploying the service library project, the content of the config file must be added to the host's 
  app.config file. System.Configuration does not support config files for libraries. -->
  <system.serviceModel>
    <services>
      <service name="WcfServiceLibrary.SecurityAccessService">
        <host>
          <baseAddresses>
            <add baseAddress = "http://localhost:8732/Design_Time_Addresses/WcfServiceLibrary/ISecurityAccessService/" />
          </baseAddresses>
        </host>
        <!-- Service Endpoints -->
        <!-- Unless fully qualified, address is relative to base address supplied above -->
        <endpoint address ="" binding="wsHttpBinding" contract="WcfServiceLibrary.ISecurityAccessService">
          <!-- 
              Upon deployment, the following identity element should be removed or replaced to reflect the 
              identity under which the deployed service runs.  If removed, WCF will infer an appropriate identity 
              automatically.
          -->
          <identity>
            <dns value="localhost"/>
          </identity>
        </endpoint>
        <!-- Metadata Endpoints -->
        <!-- The Metadata Exchange endpoint is used by the service to describe itself to clients. --> 
        <!-- This endpoint does not use a secure binding and should be secured or removed before deployment -->
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <!-- To avoid disclosing metadata information, 
          set the value below to false and remove the metadata endpoint above before deployment -->
          <serviceMetadata httpGetEnabled="True"/>
          <!-- To receive exception details in faults for debugging purposes, 
          set the value below to true.  Set to false before deployment 
          to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="False" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>

</configuration>

Обновление 1

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

Скачать полный пример 40ko .rar

Ответы [ 2 ]

1 голос
/ 27 мая 2011

ваш класс User должен быть помечен атрибутом DataContract, а его методы - атрибутом DataMember. Возможно, его также необходимо пометить как KnownType в классе CompositeUser, чтобы включить его в типы для службы. Вы можете сделать это так:

[DataContract]
[KnownType(typeof(User))]
public class CompositeUser
{
...
}

вы сможете определить причину проблемы по логам. Либо вы получите сообщение «невозможно сериализовать», в этом случае вам нужно будет добавить атрибут [DataContract], либо это будет «тип не ожидался», и в этом случае вам также потребуется добавить атрибут [KnownType]

Если вы включите трассировку в своем сервисе, вы сможете получить более подробную информацию о проблеме. Добавьте что-то вроде этого в файл конфигурации:

<configuration>
  <system.diagnostics>
     <trace autoflush="true"/>
      <sources>
         <source name="System.ServiceModel" switchValue="Verbose">
            <listeners>
               <add name="sdt" type="System.Diagnostics.XmlWriterTraceListener" initializeData="D:\wcfLog.svcLog"/>
           </listeners>
         </source>
      </sources>
    </system.diagnostics>
</configuration>

также настройка <serviceDebug includeExceptionDetailInFaults="True" />

позволит получить более подробную информацию об ошибке в исключении службы, что также может помочь.

EDIT

Из комментариев ниже кажется, что класс User является классом, сгенерированным Linq to SQL. Я не думаю, что вы должны посылать этот класс по проводам. WCF имеет дело с сообщениями, не относящимися к сериализации типов с поведением, поэтому вы должны создать DTO, который представляет данные вашего класса User, которые будут необходимы клиенту, и отправить это DTO из контракта на обслуживание. Даже если вы отправите класс User таким, какой он есть, при получении клиентом у него не будет контекста для подключения к БД.

0 голосов
/ 13 апреля 2012

Я снова столкнулся с этой проблемой сегодня.Давным-давно у меня была такая же проблема, но я забыл причину, и мне потребовалось некоторое время, чтобы разобраться с ней.

В моем случае это была проблема циклической сериализации.В одной таблице есть столбец, который является внешним ключом для другого столбца в той же таблице.Поэтому все, что мне нужно было сделать, - это щелкнуть рабочую поверхность файла dbml и изменить режим сериализации на однонаправленный.

Если у вас ситуация Linq to Sql и сообщение об ошибке показано выше,Возможно, вы захотите проверить, является ли это той же причиной, что и моя.

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