Jul 26 2009
IList and Round-trip Serialization Issue in WCF
Problem
WCF throws System.ExecutionEngineException when deserializing and consuming data contracts with IList based attributes.
Forces
- Collection is changed as immutable when using IList<T>
- Unable to convert it to List<T>
- Unable to send it back to service consumer if required
Solution
Let us define a data contract Dump which contains IList of InternalDump.
[DataContract]
public class InternalDump
{
[DataMember]
public string Part;
}
[DataContract]
public class Dump
{
[DataMember]
public string Name;
[DataMember]
public IList<InternalDump> Parts;
public Dump()
{
Parts = new List<InternalDump>();
}
}
I’ve declared a simple WCF service
[ServiceContract]
public interface IService1
{
[OperationContract]
Dump GetData(Dump d);
}
public class Service1 : IService1
{
public Dump GetData(Dump d)
{
return d;
}
}
You are noticed that GetData just returns the deserialized “d” as a return value to the consumer. Being a .NET client, the consumer of this service as
Dump d = new Dump();
d.Name = "Roundtrip";
InternalDump id = new InternalDump();
id.Part = "Client";
d.Parts.Add(id);
ServiceReference1.Service1Client sc = new DumpConsole.ServiceReference1.Service1Client();
Dump sd = sc.GetData(d);
foreach (InternalDump id2 in sd.Parts)
{
Console.Write(id2.Part);
}
At the consumer side, a new instance of Dump and InternalDump have been created, serialized and send it as input parameter for GetData. At the service side, the probelm is when deserializing the IList<InternalDump>, WCF internally convert it into InternalDump[] which makes all the problem 1 and 2 mentioned in Forces section.
The problem is not in any of the above code, instead WCF itself. The world’s so extensible ESB (enterprise service bus) framework assumed and convert IList<T> into T[] for platform neutral.
Unfortunately, do not know the root cause of problem 3 mentioned in “Forces” section. The solution is not the technical one, but a guideline.
Don’t use IList<T> for the above mentioned probelms. Instead use List<T>.
Hope WCF in .NET 4.0 will resolve this issue.










Oct 09, 2009 @ 15:49:39
This is a Bug in WCF and .NET 3.5, it is fixed in the latest version. using List will help you avoid the issue.
Nov 13, 2009 @ 07:50:54
Thanks for the information.
Dec 08, 2009 @ 00:55:48
Latest .net 3.5 sp1 fix this issues … but only on Windows 7. The same code runs ok on windows 7 but give all sorts of trouble when running on windows XP or windows 2003.
Jan 20, 2010 @ 07:32:38
Thanks Phyo.
Feb 22, 2011 @ 15:46:57
Hi All expert
How can I return an IList in WCF service?
Example (Do this to paging in WCF and NHibernate):
- want to get all students have class id = classID
- Add matched students and it’s total in to an IList then return that IList
- On client site use javascript to get students objects and the total
Below is my example:
public IList Get_StudentByClass(string classID)
{
using (ISession session = _sessionFactory.OpenSession())
{
ICriteria criteria = session.CreateCriteria(typeof(StudentObj));
IMultiCriteria multiCriteria = session.CreateMultiCriteria();
criteria.CreateAlias(“classObj”, “clAlias”);
criteria.Add(Expression.Eq(“clAlias.ClassID”, Convert.ToInt32(classID)));
using (ITransaction tx = session.BeginTransaction())
{
IList multiResults = multiCriteria
.Add(criteria.SetMaxResults(5))
.Add(criteria.SetProjection(Projections.RowCount()))
.List();
IList results = new ArrayList();
IList students = (IList)multiResults[0];
IList counts = (IList)multiResults[1];
int count = (int)counts[0];
results.Add(students);
results.Add(counts);
tx.Commit();
session.Evict(criteria);
session.Flush();
session.Dispose();
_sessionFactory.Dispose();
_sessionFactory.Close();
results.Add(matchObjects);
return results;
}
}
}
Thanks in advance