In .NET, a collection is any type that supports the IEnumerable or IEnumerable<T> interface.
All of the built-in collections in .NET, such as the array, the list, and the stack,support these interfaces.
A data contract can include a collection as a data member,and a service contract can define operations that interact with a collection directly.
Whenever you define a service operation that uses the collection interfaces IEnumerable<T>, IList<T>, or ICollection<T>, the resulting metadata always uses an array.
Collection type in .net
http://msdn.microsoft.com/en-us/library/system.collections(v=vs.80).aspx
Collection Types in WCF Example :
Service Interface :
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.ServiceModel;
namespace WCF_DataContract_CollectionType
{
[ServiceContract]
public interface IService1
{
[OperationContract] //
IEnumerable<Item> Getorder();
[OperationContract]
List<Item>
GetorderList();
[OperationContract]
ICollection<Item>
GetorderICollection();
[OperationContract]
void add(Item i);
}
public class Item
{
public int itemid { get; set; }
public string
ItemName { get; set;
}
}
}
Service
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
using System.Xml;
using System.IO;
namespace WCF_DataContract_CollectionType
{
public class Service1 : IService1
{
List<Item>
objlst = new List<Item>();
Item _obj2;
// This method add data to list
public void AddData()
{
_obj2 = new Item();
_obj2.itemid = 3001;
_obj2.ItemName = "Mobiles";
objlst.Add(_obj2);
_obj2 = new Item();
_obj2.itemid = 3002;
_obj2.ItemName = "LCD";
objlst.Add(_obj2);
}
public void add(Item i)
{
//we can use this method to add data into database table
//we can access Properties of Item class like this
// i.itemid.ToString()
----//90001
//i.ItemName.ToString() -----/ Client side
}
public IEnumerable<Item>
Getorder()
{
AddData(); // this function add data to list and returnlist
return objlst;
}
public ICollection<Item> GetorderICollection()
{
AddData();
return objlst;
}
public List<Item> GetorderList()
{
AddData();
return objlst;
}
}
}
Client side
using System;
using System.Collections;
using System.Linq;
using System.Text;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.ServiceModel;
namespace Client
{
class Program
{
static void Main(string[] args)
{
SC1.Service1Client obj = new SC1.Service1Client();
SC1.Item _obj2;
_obj2 = new SC1.Item();
_obj2.itemid = 90001;
_obj2.ItemName = "ClientSide";
obj.add(_obj2);
Console.WriteLine("
");
Console.WriteLine("****** IEnumerable Method called ********** ");
Console.WriteLine("
");
SC1.Item[] itemd = obj.Getorder();
for (Int32 l = 0;
l < itemd.Length; l++)
{
Console.WriteLine("Item {0}
ItemName {1}", itemd[l].itemid, itemd[l].ItemName);
}
Console.WriteLine("
");
Console.WriteLine("****** List Method called ********** ");
Console.WriteLine("
");
List<SC1.Item>
itemlist = obj.GetorderList().ToList();
for (Int32 l = 0;
l < itemlist.Count; l++)
{
Console.WriteLine("Item {0}
ItemName {1}", itemd[l].itemid, itemd[l].ItemName);
}
Console.WriteLine("
");
Console.WriteLine("****** ICollection Method called ********** ");
Console.WriteLine("
");
SC1.Item[]
itemIcoll = obj.GetorderICollection();
for (Int32 l = 0;
l < itemlist.Count; l++)
{
Console.WriteLine("Item
{0} ItemName {1}",
itemd[l].itemid, itemd[l].ItemName);
}
Console.ReadLine();
}
}
}
OutPut
****** IEnumerable Method called **********
Item 3001 ItemName Mobiles
Item 3002 ItemName LCD
****** List Method called **********
Item 3001 ItemName Mobiles
Item 3002 ItemName LCD
****** ICollection Method called **********
Item 3001 ItemName Mobiles
Item 3002 ItemName LCD
Note:
When we add service reference than click on advance it will open Service reference settings where collection type by default System.Array.
Click object browser and you can see that array has been returned in metadata instead of
collection as shown in fig below. In this case we need to cast to Tolist() List<SC1.Item> itemlist = obj.GetorderList().ToList();
Otherwise complietime error will
generated
Error 1Cannot implicitly convert type 'Client.SC1.Item[]' to 'System.Collections.Generic.List<Client.SC1.Item>' C:\Users\vikas.kumar\Desktop\WCF
Experiments\WCF-DataContract-CollectionType\Client\Program.cs 36 36 Client
Solution is we
can call getorderlist() method as below because we are returning collection from client side
but we are getting array on client side
SC1.Item[] itemlist = obj.GetorderList();
Return List instead of array
Right click on Configure service reference it will open Service reference settings window wwhere u can use generic list in array collection.
With this change method calling
List<SC1.Item>
itemlist = obj.GetorderList(); will work fine.
But other methods SC1.Item[] itemd
= obj.Getorder(); will give error message like
Error 1 Cannot implicitly convert type 'System.Collections.Generic.List<Client.SC1.Item>' to 'Client.SC1.Item[]' C:\Users\vikas.kumar\Desktop\WCF Experiments\WCF-DataContract-CollectionType\Client\Program.cs 32 31 Client
Solution is either change
return type
List<SC1.Item>
itemd = obj.Getorder();
Or
use casting
SC1.Item[] itemd
= obj.Getorder().ToArray() ;
Custom collection in WCF
Custom collection must have
- Add method
- Implement IEnumerable and IEnumerable<T>
- Custom collection is serlializable
Custom
collection class
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
namespace WCF_CustomCollection
{
[Serializable]
public class CustomClass<T> : IEnumerable<T>
{
private List<T>
myList = new List<T>();
public void
AddRecord(T c)
{
myList.Add(c);
}
// IEnumerable<T> extends IEnumerable interface,
therefore
//the compiler expects you to implement two versions of the
GetEnumerator() method
// we need to implement both versions of GetEnumerator().
IEnumerator<T> IEnumerable<T>.GetEnumerator()
{
return myList.GetEnumerator();
}
System.Collections.IEnumerator IEnumerable.GetEnumerator()
{
return myList.GetEnumerator();
}
}
}
Interface :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
namespace WCF_CustomCollection
{
[ServiceContract]
public interface IService1
{
[OperationContract]
CustomClass<Item>
Getorder();
[OperationContract]
void AddRecord(Item
i);
}
//item Class
public class Item
{
public int itemid { get; set; }
public string
ItemName { get; set;
}
}
}
Service :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
namespace WCF_CustomCollection
{
public class Service1 : IService1
{
CustomClass<Item>
objlst = new CustomClass<Item>();
Item _obj2;
public void AddData()
{
_obj2 = new Item();
_obj2.itemid = 3001;
_obj2.ItemName = "Mobiles";
objlst.AddRecord(_obj2);
_obj2 = new Item();
_obj2.itemid = 3002;
_obj2.ItemName = "LCD";
objlst.AddRecord(_obj2);
}
public void
AddRecord(Item i)
{
}
public CustomClass<Item> Getorder()
{
AddData();
return objlst;
}
}
}
Client side
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ClientConsole
{
class Program
{
static void Main(string[] args)
{
SC1.Service1Client obj = new SC1.Service1Client();
Console.WriteLine(" ");
Console.WriteLine("****** IEnumerable Method called ********** ");
Console.WriteLine("
");
SC1.Item[] itemd =
obj.Getorder().myList.ToArray() ;
for (Int32 l = 0;
l < itemd.Length; l++)
{
Console.WriteLine("Item {0}
ItemName {1}", itemd[l].itemid, itemd[l].ItemName);
}
Console.WriteLine("
");
Console.WriteLine("****** List Method called ********** ");
Console.WriteLine("
");
List<SC1.Item>
itemlist = obj.Getorder().myList;
for (Int32 l = 0;
l < itemlist.Count; l++)
{
Console.WriteLine("Item {0}
ItemName {1}", itemd[l].itemid, itemd[l].ItemName);
}
Console.ReadLine();
}
}
}