При вызове IEnumerable через службу WCF, я получаю Базовое соединение было закрыто ошибка - PullRequest
3 голосов
/ 05 апреля 2011

Немного предыстории в моем вопросе ...

У меня есть веб-сайт и несколько консольных приложений, которые получают доступ к одному и тому же слою данных (Linq-To-Sql) для установки / получения данных.Консольные приложения работают в нашей сети, и все они обновляют центральную базу данных с помощью служб WCF.Веб-сайт используется для отображения данных, собранных с помощью данных приложений для пользователей.

Мои службы WCF работают, когда я возвращаю простые типы, и когда я возвращаю списки своих пользовательских объектов, НО мой сервис падает с ошибкой «базовое соединение было закрыто» всякий раз, когда я пытаюсь вернуть что-либо в пределахIEnumerable / IQueryable.

Я думал, что можно вернуть IEnumerables / IQueryables через службы WCF?Возможно ли это, или я просто неправильно настраиваю свой сервис?Я использую basicHttpBinding вместо wsHttpBinding, но я все еще не на 100% уверен, в какой ситуации лучше использовать разные типы.

Моя установка выглядит следующим образом:

public class CageService : ICageRepository
{
        public IEnumerable<Cage> GetAll()
        {
            var dc = new DataContext();
            return dc .GetAll();
        }
}


[ServiceContract]
public interface ICageRepository : IRepository<Cage>
{
    [OperationContract]
    IEnumerable<Cage> GetAll();

}

Service Config:

  <system.serviceModel>

    <services>
      <!-- Note: the service name must match the configuration name for the service implementation. -->
      <service name="CageService" behaviorConfiguration="CageServiceTypeBehaviors" >
        <host>
          <baseAddresses>
            <add baseAddress = "http://localhost/UHFWebsite/" />
          </baseAddresses>
        </host>
        <!-- Add the following endpoint.  -->
        <!-- Note: your service must have an http base address to add this endpoint. -->
        <endpoint contract="IMetadataExchange" binding="mexHttpBinding" address="mex" />


        <endpoint address ="" binding="basicHttpBinding" contract="Wavin.CageTracking.DataLayer.Interfaces.ICageRepository" />
      </service>
    </services>

    <behaviors>
      <serviceBehaviors>
        <behavior name="CageServiceTypeBehaviors" >
          <!-- Add the following element to your service behavior configuration. -->
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>

  </system.serviceModel>

Клиентская конфигурация:

<system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="BasicHttpBinding_ICageRepository1" closeTimeout="00:01:00"
          openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
          allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
          maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
          messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
          useDefaultWebProxy="true">
          <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
            maxBytesPerRead="4096" maxNameTableCharCount="16384" />
          <security mode="None">
            <transport clientCredentialType="None" proxyCredentialType="None"
              realm="" />
            <message clientCredentialType="UserName" algorithmSuite="Default" />


          </security>
        </binding>
      </basicHttpBinding>
    </bindings>
    <client>
      <endpoint address="http://localhost:2000/UHFServices/CageService.svc"
        binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_ICageRepository1"
        contract="CageRepositoryClient.ICageRepository" name="BasicHttpBinding_ICageRepository1" />
    </client>
  </system.serviceModel>

код вызова выглядит так:

void method()
{
            var client = new CageRepositoryClient();
            CageListView.DataSource = client.GetAll();;
            CageListView.DataBind();
}

Ответы [ 3 ]

6 голосов
/ 05 апреля 2011

Вам нужно добавить класс Cage к известным типам вашего сервиса при реализации вашего интерфейса.

[ServiceBehavior]
[ServiceKnownType(typeof(Cage))] 
public class CageRepository: ICageRepository
{
...
2 голосов
/ 05 апреля 2011

Есть ли причина, по которой это простое изменение не работает? Если так, то в чем ошибка?

public IEnumerable<Cage> GetAll()
{
    var dc = new DataContext();
    return dc.GetAll().ToList();
}

Редактировать. Из вашего поста складывается впечатление, что вы можете подумать, что IEnumerable является запросом linq. Это не тот случай, это просто последовательность предметов типа T.

Это совершенно правильный оператор, который создает IEnumerable, например, из объекта List.

IEnumerable<int> ints = new List<int>(new int[] { 1, 2, 3 });
2 голосов
/ 05 апреля 2011

Похоже, вы не набираете ToList() данных, которые вы возвращаете из контекста данных.Обычно это является причиной проблемы с ORM, поскольку вы возвращаете не данные, а сам запрос.

Поэтому вам нужно использовать:

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