views:

235

answers:

1
+1  Q: 

HashSet in WCF

hi friends,

i'm using a HashSet in my WCF interface

[ServiceContract]
public interface IwcfServerSync
{
    [OperationContract]
    void Test(HashSet<int> someHashSet);
}

When i create a service reference the HashSet turns into a int[].

I added a ServiceKnownType :

[ServiceKnownType(typeof(System.Collections.Generic.HashSet<int>))]

and tried some configuration but couldn't quite make it to change.

if i change it hard-coded everything works, but it's really annoying to change it every time a update my reference..

i'm probably doing something wrong, any pointers or ideas?

+2  A: 

Collections are simplified when they go over the wire. You can specify the collection-type via the IDE and command-line (svcutil /collectionType), but it will apply to all collections on the API. I think you should just accept it, and handle the mismatch through code. Ultimately, on the wire, collections are just xml (over the standard bindings, at least) - something like:

<items>
   <item ...>...</item>
   <item ...>...</item>
   <item ...>...</item>
</items>

- hence why it can't tell (from the schema) between an array (T[]), a List<T>, a HashSet<T>, and a MyFunkyCollection<T>.

Note that if you use assembly sharing (i.e. the same service contract assembly is at the client and server) then this won't happen - but that defeats the intent of SOA/mex. But is is an approach used quite a lot - hence the IDE supports it directly, and command-line via a switch (svcutil /reference).


For the IDE supporting it... if you write the service contract and data contract in a class library (dll), and then add an assembly reference (i.e. a dll reference or a project reference) to this library from the two projects (the server project and the client project). Now add a service reference from the client project to the server endpoint (the .svc). If you are using VS2008, it will automatically check local references for types and use those in place of proxy generation - meaning: your client code uses the IwcfServerSync from the class library, which already knows whether to use HashSet<T> etc.

Marc Gravell
thanks for the answer,i already got the "handle the mismatch through code" from a colleague :) just wanted to know if there's a better solution..actually i don't mind that the service contract is in a shared assembly, i switched from remoting and the client do know the interface (building a game and need to move objects between ths iis and the game server all writen by self).i just can't find where the IDE supports it..
ohh.. that's right i need to use the interface, but for some reason the IDE still creates the interface and use it to implement the proxy.what did i miss this time?
That is odd... you can try adding the class library to the "Reuse types in specified referenced assemblies" list? http://blogs.microsoft.co.il/blogs/kolbis/archive/2008/06/08/reusing-types-in-wcf.aspx
Marc Gravell
thanks for the support!I tried the "reuse" thing ofcourse - didn't work for some reason.in the end I decided not to use the IDE nor the svcutil.exe, it's hard to control them - changing OperationContract signatures (moving out params order) and some generics to arrays, so the maintenance will be hard (again, i have two apps wrote by self, so it's not real "outside" services)just wrote it manualy:public class MyClass : ClientBase<WCFInterface>, WCFInterfacethere is a good guide and more tips for beginers how to do so here : http://www.devx.com/codemag/Article/39837/1763/page/1