Problem
WCF throws System.ExecutionEngineException when deserializing and consuming data contracts with IList based attributes.
Forces
- Collection is changed as immutable when using IList
- Unable to convert it to List
- 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 IListParts; public Dump() { Parts = new List (); } }
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
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
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
Hope WCF in .NET 4.0 will resolve this issue.
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.
Thanks for the information.
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.
Thanks Phyo.
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