views:

242

answers:

2

Hi,

I have a quite simple WCF service method which returns an IQueryable, just for testing. Perhaps I got something wrong when trying to understand what IQueryable is designed for. I clearly plan to use this with the IQueryable provider of NHibernate later. But first I ran into some sort of serialization problems (at least I think it might be the problem) whenever using a WCF method returning an IQueryable. It doesn't even work for a simple string.

Here's my code:

public IQueryable<string> GetEquipmentConfigurations()
{
  var returnValue = new List<string>();
  returnValue.Add("test");
  return returnValue.AsQueryable();
}

It might not have much sense, it's just for testing whether I really get those IQueryables over the wire using WCF. Whenever I call this method using a client like SoapUI I get a socket exception and a connection reset, just the same as if I was trying to return something that is not marked as DataContract. But the only thing I do here is trying to return some lousy string list. What's wrong with that?

I use basicHTTPBinding, here are my settings:

<system.serviceModel>
   <services>
      <service name="EquipmentConfigurationService" behaviorConfiguration="DefaultBehavior">
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8000/Krones.KBase/Services/EquipmentConfigurationService"/&gt;
          </baseAddresses>
        </host>
        <endpoint address=""
                  binding="basicHttpBinding"
                  contract="Krones.MES.KBase.Public.Service.EquipmentDefinition.IEquipmentConfigurationService" />
        <endpoint address="mex"
                  binding="mexHttpBinding"
                  contract="IMetadataExchange" />
      </service>
   </services>
   <behaviors>
      <serviceBehaviors>
         <behavior name="DefaultBehavior">
            <serviceMetadata httpGetEnabled="True"/>
            <serviceDebug includeExceptionDetailInFaults="True"/>
         </behavior>
      </serviceBehaviors>
   </behaviors>
</system.serviceModel>

The OperationContract attribute is set for the interface:

[OperationContract]
IQueryable<string> GetEquipmentConfigurations();

It all works well when just returning a simple string. Anyway I want to take profit from the IQueryable features using LINQ later.

Anybody any idea what's going wrong here?

Thanks and Cheers,

Stefan

+4  A: 

Hi

AFAIK it isn't possible out of the box to serialize IQueryable (think about it - it would mean that the expression tree / lambda would need to be serialized and the function rebuilt)

However, where there is a will, it seems there is a way - you might want to look at projects such as this http://code.msdn.microsoft.com/exprserialization

Good luck!

HTH

nonnb
OK, but then I don't understand how WCF Ria services work - they seem to be using IQueryables and expose them to the client using some sort of webservice technique. How do they manage this? As far as I understood this was one of the major benefits of WCF Ria services, to tunnel the LINQ queries from the client through a webservice down to the serialization engine... ?
Pilsator
+6  A: 

The core WCF is designed to send data, not queries. Stick to returning List<Foo> etc; it'll save you much head-scratching.

However, you might have more luck doing what you are after with WCF Data Services, which allows you to expose IQueryable<> sources.

The way this works is that the tooling builds a client that exposes similar looking IQueryable<> hooks; when you query data, it represents the expression on the wire, queries the data and brings it back to the client. But it is still the results (not the query) that goes over the wire.

Marc Gravell