Objective
In this article, I will explain you what is CollectionDataContract Attribute in WCF and why need it?
Why we need it?
If you notice when we expose a custom collection, it must have
- Add method
- Implement IEnumerable and IEnumerable<T>
- Custom collection is serlializable
Now let us go ahead and remove these two things which we added before in our custom collection
Previously the custom collection was
Now even if you remove the entire three prerequisite to work with custom collection and modify this custom collection as
And work with above custom collection you will not get any compile or run time error. So as the result, you would end up with corrupted data at the client side.
One more problem in above approach is that we have to put serlializable attribute explicitly.
And at the client side we are working with array and at the service side it is custom collection.
So, to solve above three problems we do have CollectionDataContract attribute.
So, now go ahead and modify the custom collection as below,
- Open the MyCustomCollection class .
- Add the name space System.Runtime.Serialization
- Put the attribute CollectionDataContract
Here if you notice, I am providing the name value in the constructor of CollectionDataContract . This name (MyCollection) will be exposed as the name of generic link list at the client side.
So entire MyCollection class will look like,
MyCollection.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Collections;
using System.Runtime.Serialization;
namespace CRUDOperation
{
[CollectionDataContract(Name="MyCollectionof{0}")]
public class MyCustomCollection<T>
: IEnumerable<T>
{
private
List<T> myList = new List<T>();
public void Add(T c)
{
myList.Add(c);
}
IEnumerator<T>
IEnumerable<T>.GetEnumerator()
{
return
myList.GetEnumerator();
}
System.Collections.IEnumerator IEnumerable.GetEnumerator()
{
return
myList.GetEnumerator();
}
}
}
Now I will use this custom class in service and expose it to the client as
IService1.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
using System.Runtime.Serialization;
namespace CRUDOperation
{
[ServiceContract]
public interface IService1
{
[OperationContract]
MyCustomCollection<Student> GetStudents();
[OperationContract]
void
Add(Student s);
}
}
Student.cs
public class Student
{
public string RollNumber { get; set; }
public string Name { get; set; }
}
Service1.svc.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
namespace CRUDOperation
{
public class Service1 : IService1
{
MyCustomCollection<Student> lstStudent = new
MyCustomCollection<Student>();
public MyCustomCollection<Student>
GetStudents()
{
return
lstStudent;
}
public void Add(Student
s)
{
lstStudent.Add(s);
}
}
}
Now when you expose this service at the client side, in the Meta data of service the custom collection will be exposed as generic link list.
Let us say you have added the service in the client by choosing add service reference. Now click on the object explorer and Service1Client class, you can see that GetStudents class return type is MyCollectionOfStudent.
If you remember, I have given the name attribute of the CollectionDataContract attribute as MyCollectionOf{0} . So it has taken Student as the parameter and return type is exposed as MyCollectionOfStudent.
If you closely notice the object explorer you will find there is a class called MyCollectionOfStudent has been created.
So at the client side we can access the custom collection as below,
So complete client code can be as below,
Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ConsoleApplication1.ServiceReference1;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[]
args)
{
Service1Client
proxy = new Service1Client();
proxy.Add(new
Student { RollNumber = "1", Name = "DJ"
});
MyCollectionofStudent
students = proxy.GetStudents();
foreach
(var r in
students)
{
Console.WriteLine(r.Name);
}
Console.Read();
}
}
}
Conclusion
I hope this article was useful to you. Thanks for reading. Happy coding.