WCF use DataContractSerializer serialization engine to translates between .NET Framework objects and
XML.
WCF also
includes a companion serializer, the NetDataContractSerializer.
The NetDataContractSerializer is
similar to the BinaryFormatter and SoapFormatter serializers because it also
emits .NET Framework type names as part of the serialized data.
Windows Communication Foundation supports three serializers:
- · XmlSerializer,
- · DataContractSerializer
- · NetDataContractSerializer
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_Serialization
{
[ServiceContract]
public interface ICustomerDetails
{
[OperationContract]
CustomerDetails GetCustomers();
}
[DataContract]
public class CustomerDetails
{
private int _Cid;
private string
_CName;
private DateTime _CDob;
public int CustomerID
{
get { return _Cid; }
set { _Cid = value; }
}
[DataMember]
public string
CustomerName
{
get { return _CName;
}
set { _CName = value;
}
}
[DataMember]
public DateTime CustomerDOB
{
get { return _CDob; }
set { _CDob = value;
}
}
}
}
Service :
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.Xml;
using System.IO;
namespace WCF_Serialization
{
public class Service1 : ICustomerDetails
{
CustomerDetails _obj;
public CustomerDetails
GetCustomers()
{
_obj = new CustomerDetails();
_obj.CustomerID = 1001;
_obj.CustomerName = "Virat Kohli";
_obj.CustomerDOB = DateTime.Now.AddYears(-30);
_obj = new CustomerDetails();
_obj.CustomerID = 1002;
_obj.CustomerName = "joe Root";
_obj.CustomerDOB = DateTime.Now.AddYears(-30);
DataContractSerializer ds = new DataContractSerializer(typeof(CustomerDetails));
// This part is user to Serialize Funddetail Class /
XmlWriterSettings settings = new XmlWriterSettings()
{ Indent = true };
using (XmlWriter w
= XmlWriter.Create(@"C:\Users\vikas.kumar\Desktop\WCF
Experiments\WCF-Serialization\WCF-Serialization\cuatomerdetails.xml",
settings))
ds.WriteObject(w, _obj);
System.Diagnostics.Process.Start(@"C:\Users\vikas.kumar\Desktop\WCF
Experiments\WCF-Serialization\WCF-Serialization\cuatomerdetails.xml");
// Deserialize the data and read it from the instance.
FileStream fs = new
FileStream(@"C:\Users\vikas.kumar\Desktop\WCF
Experiments\WCF-Serialization\WCF-Serialization\cuatomerdetails.xml",
FileMode.Open);
XmlDictionaryReader reader = XmlDictionaryReader.CreateTextReader(fs, new XmlDictionaryReaderQuotas());
DataContractSerializer ser = new DataContractSerializer(typeof(CustomerDetails));
CustomerDetails dser = (CustomerDetails)ser.ReadObject(reader,
true);
reader.Close();
fs.Close();
return _obj;
}
}
}
Client :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Xml;
namespace Client
{
class Program
{
static void Main(string[] args)
{
ServiceReference1.CustomerDetailsClient
obj = new ServiceReference1.CustomerDetailsClient();
obj.GetCustomers();
}
}
}
Outpt:
<?xml version="1.0" encoding="UTF-8"?>
-<Customer xmlns="http://schemas.datacontract.org/2004/07/WCF_Serialization" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<CustomerAutoID>1002</CustomerAutoID>
<CustomerFullName>joe Root</CustomerFullName>
<DateOfBirth>1983-03-11T15:37:48.2931458+04:00</DateOfBirth>
</Customer>
Ordering of elements
is alphabetic order
Test 1 :
Change data contract members :
Here we have altered the name of the XML Elements,
Namespace and ordering of the elements.
[DataContract(Name
= "Customer", Namespace = "http://wcftest1.com/Customer")]
public class CustomerDetails
{
private int _Cid;
private string
_CName;
private DateTime _CDob;
[DataMember(Name
= "CustomerAutoID", Order = 3)]
public int CustomerID
{
get { return _Cid; }
set { _Cid = value; }
}
[DataMember(Name
= "CustomerFullName", Order =
1)]
public string
CustomerName
{
get { return _CName;
}
set { _CName = value;
}
}
[DataMember(Name
= "DateOfBirth", Order = 2)]
public DateTime
CustomerDOB
{
get { return _CDob; }
set { _CDob = value;
}
}
}
Output :
<?xml version="1.0" encoding="UTF-8"?>
-<Customer xmlns="http://wcftest1.com/Customer" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<CustomerFullName>joe Root</CustomerFullName>
<DateOfBirth>1983-03-11T15:37:48.2931458+04:00</DateOfBirth>
<CustomerAutoID>1002</CustomerAutoID>
</Customer>
Test 2 :
In this
test we are removing DataMember attribute from customer name property and adding two
more data members Country
and Salary with default
value null.
The
EmitDefaultValue parameter of the DataMember
attribute country set to false
[DataContract(Name = "Customer",
Namespace = "http://wcftest1.com/Customer")]
public class CustomerDetails
{
private int _Cid;
private string
_CName;
private DateTime _CDob;
//private double _sal;
private string
_country;
[DataMember(Name = "CustomerAutoID",
Order = 2)]
public int CustomerID
{
get { return _Cid; }
set { _Cid = value; }
}
public string CustomerName
{
get
{ return _CName; }
set
{ _CName = value; }
}
[DataMember(Name = "DateOfBirth",
Order = 1)]
public DateTime
CustomerDOB
{
get { return _CDob; }
set { _CDob = value;
}
}
[DataMember(Name
= "CustomerCountry", Order = 3,
EmitDefaultValue=false)]
public string Country =null;
[DataMember(Order
= 4)]
public string Salary = null;
}
Output:
In output we can see CustomerName properity is
not serialized because it is not declared as datamember
<?xml version="1.0" encoding="UTF-8"?>
-<Customer xmlns="http://wcftest1.com/Customer" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<DateOfBirth>1983-03-11T16:01:27.3231002+04:00</DateOfBirth>
<CustomerAutoID>1002</CustomerAutoID>
<Salary i:nil="true"/>
</Customer>
Types
Supported by the Data Contract Serializer
Data contract types. These are types to which the DataContractAttribute attribute has been
applied.
All public fields, and properties with public get and set methods are
serialized, unless you apply the IgnoreDataMemberAttribute attribute to that member.
Collection types. These can be regular arrays of types, or collection types, such as ArrayList and Dictionary. The CollectionDataContractAttribute attribute can be used
to customize the serialization of these types, but is not required.
Enumeration types. Enumerations, including flag
enumerations, are serializable. Optionally, enumeration types can be marked
with the DataContractAttribute attribute, in which case every member that
participates in serialization must be marked with the EnumMemberAttribute
attribute. Members that are not marked are not serialized. For more
information, see Enumeration Types in Data Contracts.
.NET Framework primitive types. The following types built into
the .NET Framework can all be serialized and are considered to be primitive
types: Byte, SByte, Int16, Int32, Int64, UInt16, UInt32, UInt64, Single,
Double, Boolean, Char, Decimal, Object, and String.
Other primitive types. These types are not primitives in
the .NET Framework but are treated as primitives in the serialized XML form.
These types are DateTime, DateTimeOffset, TimeSpan, Guid, Uri,
XmlQualifiedName, and arrays of Byte.
XmlSerializer :
Let’s take above example and serialize class with XmlSerializer.
Service :
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.Xml;
using System.IO;
namespace WCF_Serialization
{
public class Service1 : ICustomerDetails
{
public CustomerDetails
GetCustomers()
{
CustomerDetails _obj;
OrderDetails _obj2;
_obj2 = new OrderDetails();
_obj2.orderID = 3001;
_obj2.Item = "Cloths";
_obj = new CustomerDetails();
_obj.CustomerID = 1001;
_obj.CustomerName = "Virat Kohli";
_obj.CustomerDOB = DateTime.Now.AddYears(-30);
_obj.customerorder = _obj2;
_obj2 = new OrderDetails();
_obj2.orderID = 3002;
_obj2.Item = "Electronic";
_obj = new CustomerDetails();
_obj.CustomerID = 1002;
_obj.CustomerName = "joe Root";
_obj.CustomerDOB = DateTime.Now.AddYears(-30);
_obj.customerorder = _obj2;
System.Xml.Serialization.XmlSerializer ds = new
System.Xml.Serialization.XmlSerializer(typeof(CustomerDetails));
XmlWriterSettings settings = new XmlWriterSettings()
{ Indent = true };
using (XmlWriter w
= XmlWriter.Create(@"C:\Users\vikas.kumar\Desktop\WCF
Experiments\WCF-Serialization\WCF-Serialization\cuatomerdetails.xml",
settings))
ds.Serialize(w, _obj);
System.Diagnostics.Process.Start(@"C:\Users\vikas.kumar\Desktop\WCF
Experiments\WCF-Serialization\WCF-Serialization\cuatomerdetails.xml");
return _obj;
}
}
}
Output :
<?xml version="1.0" encoding="UTF-8"?>
-<CustomerDetails xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
-<customerorder>
<orderID>3002</orderID>
<Item>Electronic</Item>
</customerorder>
<CustomerID>1002</CustomerID>
<CustomerName>joe Root</CustomerName>
<CustomerDOB>1983-03-13T11:26:24.2903215+04:00</CustomerDOB>
</CustomerDetails>
Here we can see that it includes the Customer Name too which is the public property.In case of DataContractSerializer this property is not serialized.
NetDataContractSerializer
:
DataContractSerializer uses data contract names.
NetDataContractSerializer outputs full .NET Framework assembly and type names
in the serialized XML.
This means that the known
types mechanism is not required with the NetDataContractSerializer because
the exact types to be deserialized are always known.
- The constructors do not require you to specify a root type.
- we can serialize any type with the same instance of the NetDataContractSerializer.
- The constructors do not accept a list of known types
- The constructors accept a parameter called assemblyFormat of the FormatterAssemblyStyle that maps to the AssemblyFormat property. As discussed previously, this can be used to enhance the versioning capabilities of the serializer. This is identical to the FormatterAssemblyStyle mechanism in binary or SOAP serialization.
- The constructors accept a StreamingContext parameter called context that maps to the Context property. You can use this to pass information into types being serialized. This usage is identical to that of the StreamingContext mechanism used in other System.Runtime.Serialization classes.
- The Serialize and Deserialize methods are aliases for the WriteObject and ReadObject methods. These exist to provide a more consistent programming model with binary or SOAP serialization.
NetDataContractSerializer ds = new
NetDataContractSerializer();
when we use NetDataContractSerializer, you
no longer have to supply type
information ahead of time, as illustrated here:
Since the .NET type information is found
in the XML, you don't need to specify the .NET type when deserializing either.
Output:
<?xml version="1.0" encoding="UTF-8"?>-<Customer xmlns="http://wcftest1.com/Customer" xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/" z:Assembly="WCF-Serialization,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" z:Type="WCF_Serialization.CustomerDetails" z:Id="1" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> <CustomerAutoID>1001</CustomerAutoID> <DateOfBirth>1983-03-13T12:10:13.3143215+04:00</DateOfBirth> -<Orderdetails z:Id="2" xmlns:d2p1="http://schemas.datacontract.org/2004/07/WCF_Serialization">
<d2p1:Item z:Id="3">Cloths</d2p1:Item>
<d2p1:orderID>3001</d2p1:orderID>
</Orderdetails>
</Customer>
Message
Encoding :
Service :
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.Xml;
using System.IO;
namespace WCF_Serialization
{
public class Service1 : ICustomerDetails
{
public CustomerDetails
GetCustomers()
{
CustomerDetails _obj;
OrderDetails _obj2;
_obj2 = new OrderDetails();
_obj2.orderID = 3001;
_obj2.Item = "Cloths";
_obj = new CustomerDetails();
_obj.CustomerID = 1001;
_obj.CustomerName = "Virat Kohli";
_obj.CustomerDOB = DateTime.Now.AddYears(-30);
_obj.customerorder = _obj2;
System.ServiceModel.Channels.Message
message = System.ServiceModel.Channels.Message.CreateMessage(System.ServiceModel.Channels.MessageVersion.Soap11WSAddressing10,
"http://www.ServiceContract.com/Samples/RPCExample/Name",
_obj, new DataContractSerializer(typeof(CustomerDetails)));
using (FileStream
fs = new FileStream(@"C:\Users\vikas.kumar\Desktop\WCF
Experiments\WCF-Serialization\WCF-Serialization\binary.bin", FileMode.Create))
{
using (XmlDictionaryWriter
writer =
XmlDictionaryWriter.CreateBinaryWriter(fs))
{
message.WriteMessage(writer);
}
}
System.Diagnostics.Process.Start(@"C:\Users\vikas.kumar\Desktop\WCF
Experiments\WCF-Serialization\WCF-Serialization\binary.bin");
using (FileStream
fs = File.OpenRead(@"C:\Users\vikas.kumar\Desktop\WCF
Experiments\WCF-Serialization\WCF-Serialization\binary.bin"))
{
using (XmlDictionaryReader
reader =
XmlDictionaryReader.CreateBinaryReader(fs,
XmlDictionaryReaderQuotas.Max))
{
using (System.ServiceModel.Channels.Message message1 = System.ServiceModel.Channels.Message.CreateMessage(
reader, 1024,
System.ServiceModel.Channels.MessageVersion.Soap11WSAddressing10))
{
// deserialize Person object from XML
CustomerDetails name = message1.GetBody<CustomerDetails>(
new DataContractSerializer(typeof(CustomerDetails)));
}
}
}
return _obj;
}
}
}
Output:
Enumeration Types in Data Contracts
Custom collection serialization :
Inteface
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.ServiceModel;
namespace WCF_DataContract_CollectionType
{
[ServiceContract]
public interface IService1
{
[OperationContract]
PurchaseOrder Getorder();
}
[DataContract(Name = "CustomerPurchase")]
public class PurchaseOrder
{
[DataMember(Order=1)]
public string
customerName;
[DataMember(Order = 2)]
public ICollection<Item>
Items_IcollectionItems;
[DataMember(Order = 3)]
public List<Item> Items_List;
[DataMember(Order = 4)]
public string[]
review;
}
public class Item
{
public int itemid;
public string
ItemName;
}
}
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
{
public PurchaseOrder
Getorder()
{
PurchaseOrder _obj;
_obj = new PurchaseOrder();
Item _obj2;
string[] R = { "Review1",
"review2" };
List<Item>
objlst = new List<Item>();
ICollection<Item>
objIcol = new Collection<Item>();
_obj2 = new Item();
_obj2.itemid = 3001;
_obj2.ItemName = "Mobiles";
_obj2.itemid = 3002;
_obj2.ItemName = "LCD";
objIcol.Add(_obj2);
objlst.Add(_obj2);
_obj.customerName = "Customer1";
_obj.Items_IcollectionItems
= objIcol;
_obj.Items_List = objlst;
_obj.review = R;
DataContractSerializer ds = new DataContractSerializer(typeof(PurchaseOrder));
XmlWriterSettings settings = new XmlWriterSettings()
{ Indent = true };
using (XmlWriter w
= XmlWriter.Create(@"C:\Users\vikas.kumar\Desktop\WCF
Experiments\WCF-Serialization\WCF-Serialization\cuatomerdetails.xml",
settings))
ds.WriteObject(w, _obj);
System.Diagnostics.Process.Start(@"C:\Users\vikas.kumar\Desktop\WCF
Experiments\WCF-Serialization\WCF-Serialization\cuatomerdetails.xml");
// Deserialize the data and read it from the instance.
FileStream fs = new
FileStream(@"C:\Users\vikas.kumar\Desktop\WCF
Experiments\WCF-Serialization\WCF-Serialization\cuatomerdetails.xml",
FileMode.Open);
XmlDictionaryReader reader = XmlDictionaryReader.CreateTextReader(fs, new XmlDictionaryReaderQuotas());
DataContractSerializer ser = new DataContractSerializer(typeof(PurchaseOrder));
PurchaseOrder p = (PurchaseOrder)ser.ReadObject(reader);
reader.Close();
fs.Close();
return _obj;
}
}
}
Client :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Client
{
class Program
{
static void Main(string[] args)
{
ServiceReference1.Service1Client obj
= new ServiceReference1.Service1Client();
obj.Getorder();
Console.ReadLine();
}
}
}
Output
<?xml version="1.0" encoding="UTF-8"?>
-<CustomerPurchase xmlns="http://schemas.datacontract.org/2004/07/WCF_DataContract_CollectionType" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<customerName>Customer1</customerName> -<Items_IcollectionItems>
-<Item>
<ItemName>LCD</ItemName>
<itemid>3002</itemid>
</Item>
</Items_IcollectionItems>
-<Items_List>
-<Item>
<ItemName>LCD</ItemName>
<itemid>3002</itemid>
</Item>
</Items_List> -<review xmlns:d2p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
<d2p1:string>Review1</d2p1:string>
<d2p1:string>review2</d2p1:string>
</review>
</CustomerPurchase>
your articles are good...but writing them day-by-day/weekly...as a schedule then which is so good.
ReplyDeletewhat is next article...Lavi?
HI,
DeleteThanks
Yes need to organised on schedule basis may be later.
Next I think I will work on WCF transactions and Channel Factory,Asynchronous WCF Service Operations etc
thanks for my above reply...Lavi
ReplyDeleteWCF Async operations and Channel Factory articles are good.
what is next article ....Live.
what is today article Lavi... by viswanadh
ReplyDelete