2011-04-05 15 views
3

位上,我的问题的背景...当调用一个IEnumerable在WCF服务我收到的基础连接已关闭错误

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

当我返回简单类型并返回我的自定义对象的列表时,我的WCF服务工作正常但是我的服务在底层连接被关闭时发生错误每当我尝试在IEnumerable/IQueryable的。

我认为有可能通过WCFs服务返回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(); 

} 

服务配置:

<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(); 
} 

回答

6

您需要在实现界面的过程中将Cage类添加到已知类型的服务中。

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

'Cage'可能已经是一个已知类型,没有什么可以表明它不是。 – 2011-04-05 15:17:18

+0

那正是我需要的..谢谢! – 2011-04-05 16:01:11

+0

只是出于兴趣..你能解释为什么服务将返回一个对象的列表罚款,但不会返回一个IEnumerbale对象的列表,而不首先声明该对象为已知类型? – 2011-04-06 07:49:49

2

听起来你不会在你从数据上下文中获得的数据上调用ToList()。这通常是ORM问题的原因,因为您返回的不是数据,而是查询本身。

所以你需要使用:

dataContext.All().ToList(); 
+0

我不想输入返回的调用(如果可能),这就是为什么我宁愿返回查询而不是列表。如果我添加.ToList()我然后将返回一个List不是一个IEnumerable。 – 2011-04-05 14:27:20

+1

列表可强制转换为IEnumerable。无论哪种方式您的问题是在您尝试枚举查询之前wcf连接已关闭。你需要在连接是烤面包之前将它列举出来,例如调用.ToList()或其他东西,这样你就可以得到真实的数据而不是查询了。 – asawyer 2011-04-05 14:28:49

+0

@Jon,你为什么要返回一个'IEnumerable'?我假设你对延迟执行的可能性不感兴趣,因为这对WCF服务调用来说是无意义的。Asawyer提到,“List ”与“IEnumerable ”兼容。 – 2011-04-05 14:31:01

2

有什么理由这个简单的变化是不工作?如果是这样的错误是什么?

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 }); 
+0

你的答案与我一样,因为我没有consnier List可以从IEnumerable派生。我对它的唯一问题是,我将在IEnumerable返回的每个方法上添加ToList()。但是..它确实允许我以我想要的方式继续使用界面和网站。我的最终解决方案是Flo的一个 – 2011-04-05 16:09:08

相关问题