WCF returns ArrayOfKeyValueOfintstringKeyValueOfintstring[] instead of Dictionary<int, string> and Array instread of List
Asked Answered
W

1

4

So I've spent the last several hours investigating this issue and it is clear that I am not the only one. Why are my Dictionaries and Lists being returned as Arrays?

I understand that Arrays are used as default for the sake of compatibility. WCF makes a conscious effort to distance itself from being .Net dependent. But both my Server and Client are developed in C# .Net so I'm okay.

Here is a sampling of similar questions on just StackOverflow alone:

  1. WCF service returning array instead of List
  2. Why does WCF return myObject[] instead of List like I was expecting?
  3. WCF service returning an array of dictionary
  4. WCF Proxy Returning Array instead of List EVEN THOUGH Collection Type == Generic.List
  5. WCF Returning Array instead of List EVEN THOUGH Collection Type == Generic.List
  6. Why does my WCF service return and ARRAY instead of a List ?
  7. Array instead of List in WCF Service Proxy Generated using svcutil.exe

What I have set up: Service Reference Configuration

I am generating the Proxy via this command:

 C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin>svcutil.exe /language:cs
 /out:generatedProxy.cs /config:app.config /ct:System.Collections.Generic.List`1
  http://192.168.0.99:9000/ProjectDatabase/??

My service contract looks like this:

[ServiceContract]
public interface IMyContract
{
    [OperationContract]
    [ServiceKnownType(typeof(Dictionary<int, string>))]
    Dictionary<int, string> getClassDictionary();
}

My implementation:

public Dictionary <int, string> getClassDictionary()
{
   Dictionary<int, string> myDict = new Dictionary<int, string>();
   myDict.Add(1, "Geometry");
   myDict.Add(2, "Algebra");
   myDict.Add(3, "Graph Theory");
   return myDict; 
}

Even in my Reference.svcmap I have:

<CollectionMappings>
  <CollectionMapping TypeName="System.Collections.Generic.List`1" Category="List" />
</CollectionMappings>

However, despite my best efforts and research I still get:

Dictionary<'int, string'> returning as ArrayOfKeyValueOfintstringKeyValueOfintstring[]

And:

List<'T'> returning as T[]

I feel like I've tried everything and done everything right, but I have to be missing something. So what is it? Thank you for your time, help, and consideration.

Update:

I've even attempted a route of working around the Array imposition, by writing a serializable struct and adding them to an array.

[Serializable]
public struct KeyValuePair<K, V>
{
    public K Key { get; set; }
    public V Value { get; set; }
}

However, when I return the KeyValuePair<int, string>[]. My proxy is generating a return of KeyValuePairOfintstring[].

Solution is posted below.

Ware answered 20/5, 2013 at 20:39 Comment(3)
I loved this ArrayOfKeyValueOfintstringKeyValueOfintstring[]Edentate
Why would the proxy be generated like that?Ware
Strange. I just built a new service, host, and client that returns a Dictionary<int, string> and it works just fine. Tomorrow I'll write up a new solution and see if that fixes the issue.Ware
W
4

Well I found out what was causing the serialization to be so crude.

In my ServiceContract I had the following:

[OperationContract]
List<DataTable> ShowTables();
[OperationContract]
DataTable FetchContacts(string filter = "All");
[OperationContract]
DataTable FetchUsers();
[OperationContract]
DataTable FetchDrops();

After commenting this out and recompiling my WCF Service Library, I found that everything serialized/ deserialized appropriately when generating the proxy.

It seems that when svcutil.exe encounters something that it does not know how to serialize then all bets are off. Quite literally it will ignore your commands/settings and serialize everything as gibberish like ArrayOfKeyValueOfinttringKeyValueOfintstring. So if you receive this error, you should ask yourself if svcutil.exe is able to properly serialize all of what you are returning.

I hope the identification of the source of my issue will help others in the future.

Ware answered 21/5, 2013 at 15:28 Comment(6)
Hope someone from Microsoft can say something about this. It is taking up too much of many people's time.Illassorted
is there a good way to figure out what it doesn't know how to serialize?Circus
Unfortunately, the only way I currently know how to determine the ability to serialize a given type is to use svcutil and take a look at the generated proxy - then process of elimination of types until I remove one that causes the outputted proxy to look the way it should. If I needed a given type and svcutil was spitting out garbage when I was using it - I would just write my own serializable type with the functionality that I needed.Ware
Did you ever find a way to debug/diagnose svcutil?Anaconda
I feel like I'm stuck in the same spot but I can't figure out what to change/comment out as I don't have a block of code like that in my ServiceContract ... but I am being tortured by my Lists turning into ArrayOfGibberish[] nonsense! Dear God please help ...Buckra
Had this happen on a small service with about 20 OperationContracts. All passed POCOs except for one, which used a DataTable. Everything turned into array until I commented out the operation that used DataTable. Solution: create an object to represent the data previously passed in DataTable and use that instead.Seedman

© 2022 - 2024 — McMap. All rights reserved.