当在WCF服务上调用IEnumerable时,我收到底层连接已关闭错误

本文关键字:连接 错误 服务 WCF 调用 IEnumerable 当在 | 更新日期: 2023-09-27 17:48:57

关于我的问题的一些背景…

我有一个网站和多个控制台应用程序访问相同的数据层(Linq-To-Sql)设置/获取数据。控制台应用程序在我们的网络上运行,它们都通过WCF服务更新中央数据库。该网站用于向用户显示应用程序数据捕获的数据。

我的WCF服务工作时,我返回简单的类型,当我返回我的自定义对象的列表,但我的服务摔倒与"底层连接被关闭错误",每当我尝试和IEnumerable/IQueryable返回任何东西。

我认为有可能在wcf服务上返回IEnumerables/IQueryables ?是可能的,还是我的服务配置错了?我使用的是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();
}

当在WCF服务上调用IEnumerable时,我收到底层连接已关闭错误

您需要在接口的实现中将Cage类添加到您的服务的已知类型中。

[ServiceBehavior]
[ServiceKnownType(typeof(Cage))] 
public class CageRepository: ICageRepository
{
...

听起来好像您不调用从数据上下文返回的数据的ToList()。这通常是orm问题的原因,因为您返回的不是数据,而是查询本身。

所以你需要使用:

dataContext.All().ToList();

有什么原因导致这个简单的改变不起作用吗?如果是,误差是多少?

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

编辑-我从你的帖子得到的印象是,你可能认为IEnumerable是一个linq查询。事实并非如此,它只是一个t类型的项目序列。

这是一个完全有效的语句,从一个List对象创建一个IEnumerable。

IEnumerable<int> ints = new List<int>(new int[] { 1, 2, 3 });