A Quick review of Serialization and DeSeralization events

A Quick review of Serialization and DeSeralization events

.Net provides the facility to intercept Serialization / DeSeralization by providing following events.

Serialization:
OnSerializing
OnSerialized
DeSeralization
OnDesrializing
IDeserialazationCallback

Courtesy: MCTS 70-536 Self Paced Training Kit by Microsoft

Following is the program with implementation of [OnDesrialized] event which checks if the total of the item(s) of a certain category is less than 20, it applies appropriate discount.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Runtime.Serialization;
using System.Security.Permissions;
using System.Xml.Serialization;</code>

<code>namespace CustomSerializationSample
{
[Serializable]
public class ShoppingCartItem : ISerializable
{
public int productID;
public decimal price;
public int quantity;
[XmlIgnore]
public decimal total;</code>

<code>public ShoppingCartItem(int _productID, decimal _price, int _quantity)
{
productID = _productID;
price = _price;
quantity = _quantity;
total = price * quantity;
}
public ShoppingCartItem()
{
}
[OnDeserialized]
void CalculateTotal(StreamingContext sc)
{
decimal discount;
if (total &lt; 20)
{
discount = (total / 100) * 12;
total = total - discount;
}
}
public override string ToString()
{
return "ProductID: " + this.productID + " : Price " + this.price.ToString() +
", Quantity: " + quantity + ", Disc: " + total;
}

#region ISerializable Members

public ShoppingCartItem(SerializationInfo info,
StreamingContext context)
{

productID = info.GetInt32("Product ID");
price = info.GetInt32("Price");
quantity = info.GetInt32("Quantity");
total = price * quantity;
}
[SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter = true)]
void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
{

info.AddValue("Product ID", productID);
info.AddValue("Price", price);
info.AddValue("Quantity", quantity);
}
#endregion
}
}

How to create CngKeyCreationParameters for CngKey object

CngKey : CngKey objects contain properties. Some properties must be added to a key when it is created. Other properties can be added after the key is created.

CngKeyCreationParameters: The CngKeyCreationParameters class enables you to add properties to a key as it is being created.

following code blocks explains how to create CngKeyCreationParameters object

//  Create CngKeyCreationParameters 
CngKeyCreationParameters keyParams = new CngKeyCreationParameters();

// set properties accordingly
keyParams.ExportPolicy =  CngExportPolicies.AllowArchiving;
keyParams.KeyCreationOptions = CngKeyCreationOptions.MachineKey;
keyParams.Provider = new CngProvider("someprovider");

following code block shows how to pass it CngKeyCreationParameters to CngKey object in CngKey.Create Method


CngKey mycngKey =  
       CngKey.Create(new CngAlgorithm(""), "keyName", keyParams);

Techniques To Serialize data in C Sharp

Several Techniques to serialize in .net

Using Formatters
using XmlSerialization
Implementing IXmlSerializable Interface ( will do in Later)

1. Formatters:

We can use BinaryFormatter and SoapFormatter provided in the following libs

using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Serialization.Formatters.Soap;

Both work in same pattern to Serialize and Desrialize an Object. The Difference is Object Serialized/ Desierializtion by BinarryFormatter is only useful between .Net Compliant Platforms, while Objects Serialized by SoapFormatter are Accessible by most Platforms and tools.

2.XmlSerialaztion:

Keep in mind Following:

Class to be Serilized must be specified as public.
The member need to be Serialized should also be public
provide a parameteless constructor
We often need to Control Serilization of an object into an XML Format

System.Xml.Serialization provided us with several attributes to do this such as

  • XmlAttribute
  • XmlAttribute
  • XmlIgnore
  • XmlEnum
  • And many more for eg if we want XmlSerializer not to Serialize a method, following Attibute helps

    public bool shipDateSpecified
    {
     get     {        return this.shipDateFieldSpecified;     }
     set     {        this.shipDateFieldSpecified = value;     }
    } 
    

    [System.Xml.Serialization.XmlIgnoreAttribute()]

    We may also Use XmlSchhema Defination Tool provided with framwork to generate class Which Conforns to our requiremnts or “Schema”

    And then simply Serialize those classes.

    Follow these Steps:

    Go To VS Command Prompt from Tools Menu. If you don’t have one Follow this Top Post By Matthew Cochran

    http://www.c-sharpcorner.com/UploadFile/rmcochran/CommandPromptInStudioToolsMenu01152008103357AM/CommandPromptInStudioToolsMenu.aspx

    Then

    Create Schema “xsd” file or get one you need your classes to conforn to.
    open Command Prompt

    Type: xsd.exe filePath  /classes / languages:[ CS|VB ]
    

    For eg

    Xsd c:/FolderA/Schemas/mySchema.xsd  /classes/languages:CS
    

    Open the class generated by the tool and add it in your project
    Declare the Object of that class
    Populate class members as you like them
    Call XmlSerialize .Serialize method

    that’s it job done

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Xml.Serialization;
    using System.Runtime.Serialization;
    using System.Runtime.Serialization.Formatters.Binary;
    using System.Runtime.Serialization.Formatters.Soap; </code>
    
    namespace SerializationSample
    {
    [Serializable]
    class Item : IDeserializationCallback
    {
    string name;
    int unitPrice;
    int quantity;
    [NonSerialized]
    int invoice;
    [OptionalField, NonSerialized]
    int salesTax;
    public Item(string _name, int _unitPrice, int _quantity)
    {
    name = _name;
    unitPrice = _unitPrice;
    quantity = _quantity;
    invoice = quantity * unitPrice;
    salesTax = (invoice / 100) * 15;
    }
    public override string ToString()
    {
    return "Name: " + name + " " + unitPrice + " * " + quantity + " --- " + invoice + "  Sales TAX: " + salesTax;
    }
    #region IDeserializationCallback Members
    public void OnDeserialization(object sender)
    {
    invoice = unitPrice * quantity;
    salesTax = (invoice / 100) * 15;
    }
    #endregion
    }
    }
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.IO;
    using System.Runtime.Serialization;
    using System.Runtime.Serialization.Formatters.Binary;
    using System.Runtime.Serialization.Formatters.Soap;
    using System.Xml.Serialization;
    namespace SerializationSample
    {
    class Program
    {
    public static void SerializeUsingBinFormatter(Item item)
    {
    // file path to serialize object
    string filePath = @"E:\PracticeFiles\ch4\BinFile.bin";
    FileStream fs = new FileStream(filePath, FileMode.Create);
    // declare binaryFormatter Object
    BinaryFormatter bFormatter = new BinaryFormatter();
    // Call Serialize, provide stream object and object to serialaize
    bFormatter.Serialize(fs, item);
    fs.Close();
    }
    public static Item DeSerializeUsingBinFormatter()
    {
    // file path to deserialize object
    string filePath = @"E:\PracticeFiles\ch4\BinFile.bin";
    FileStream fs = new FileStream(filePath, FileMode.Open);
    // declare binaryFormatter Object
    BinaryFormatter bFormatter = new BinaryFormatter();
    // provide stream to deserialize and Cast the result to appropriate object
    Item result = (Item)bFormatter.Deserialize(fs);
    fs.Close();
    return result;
    }
    public static void SerializeUsingSoapFormatter(Item item)
    {
    // file path to serialize object
    string filePath = @"E:\PracticeFiles\ch4\BinFile.bin";
    FileStream fs = new FileStream(filePath, FileMode.Create);
    SoapFormatter sFormatter = new SoapFormatter();
    sFormatter.Serialize(fs, item);
    fs.Close();
    }
    public static Item DeSerializeUsingSoapFormatter()
    {
    // file path to deserialize object
    string filePath = @"E:\PracticeFiles\ch4\BinFile.bin";
    FileStream fs = new FileStream(filePath, FileMode.Open);
    SoapFormatter sFormatter = new SoapFormatter();
    // provide stream to deserialize and Cast the result to appropriate object
    Item result = (Item)sFormatter.Deserialize(fs);
    fs.Close();
    return result;
    }
    static void Main(string[] args)
    {
    // Serialize using Binnary Formatter
    SerializeUsingBinFormatter(new Item("ObjectBinarySerializable", 5, 2));
    //Deserialize using Binary Formatter
    Console.WriteLine(DeSerializeUsingBinFormatter().ToString());
    // Serialize using Soap Formatter
    SerializeUsingSoapFormatter(new Item("ObjectSoapSerializable", 1111, 11));
    //Deserialize using Soap Formatter
    Console.WriteLine(DeSerializeUsingSoapFormatter().ToString());
    /*
    * Custom Serialization using  XmlSerialization
    * PurchaseOrderType is the main class, consists
    * of other object as
    * billTo of Type USAddress,
    * shipTo of Type USAddress,
    * string comment,
    * array of Type ItemsItem
    * */
    // See class USAddress
    USAddress address = new USAddress();
    address.city = "PW";
    address.country = "US";
    address.name = "asad";
    address.state = "LA";
    address.street = "123 lousiana close";
    address.zip = 22010;
    string comment = "No comments";
    ItemsItem Oitem = new ItemsItem();
    Oitem.comment = "no comment";
    Oitem.partNum = "678";
    Oitem.productName = "mouse";
    Oitem.quantity = "2";
    Oitem.USPrice = 30;
    ItemsItem[] itemArray = { Oitem };
    // See class PurchaseOrderType
    PurchaseOrderType pot = new PurchaseOrderType();
    pot.shipTo = address;
    pot.billTo = address;
    pot.comment = comment;
    pot.items = itemArray;
    pot.orderDate = DateTime.Now;
    pot.orderDateSpecified = true;
    // Create FileStream
    FileStream fs = new FileStream(@"E:\PracticeFiles\ch4\purchaseorder1.xml", FileMode.Create);
    // Create XmlSerializer Object
    XmlSerializer xs = new XmlSerializer(typeof(PurchaseOrderType));
    xs.Serialize(fs, pot);
    }
    }
    }
    

    Linq-to-SQL, Linq-to-DataSet and Linq-to-Entities

    LINQ to SQL is an O/RM (object relational mapping) implementation that was provided in the .NET Framework “Orcas” (.NET Framework version 3.5) release.

    It allows us to model a relational database using .NET classes and query those models using LINQ notation / syntax. We can query the database and perform all operations like update, insert and delete etc.

    As per MSDN: ” It provides a run-time infrastructure for managing relational data as objects”

    Linq-to-DataSets is just LINQ, but it is used to query against the ADO.NET DataSets. As per MSDN : “LINQ to DataSet makes it easier and faster to query over data cached in a DataSet object”.

    Linq-to-Entities is better and provides more flexibility and is usable with many types of data sources and is not limited to SQL Server only, like Linq-to-SQL is. It uses Entity Framework in the background, as the ORM.