The DataContractSerializer class belongs to the System.Runtime.Serialization namespace within the System.Runtime.Serialization assembly. It is used to serialize an instance of a type to XML and save it into any IO stream, XmlWriter or an XmlDictionaryWriter and deserialize back the data in XML format from the IO stream, XmlReader or XmlDictionaryReader.
You will need are three things:
1. An instance of a type that you want to serialize/deserialize.
2. An instance of DataContractSerializer class.
3. An instance of class that can read/write data into/from the IO stream or xml reader/writer.
Below is a sample code that shows you how serialize a collection of users. Lets say we have an User object whose type is declared as given below. As you can see, we need to add DataContractAttribute to the class and DataMemberAttribute to the class properties that we want to serialize. These attributes are defined in System.Runtime.Serialization namespace within System.Runtime.Serialization assembly.
[DataContract]
public class User
{
[DataMember]
public string UserName { get; set; }
[DataMember]
public int UserId { get; set; }
public User() { }
}
The UserCollection class attributed with DataContract and DataMembers is shown below.
[DataContract]
public class UserCollection : IEnumerable<User>
{
private List<User> _Users;
[DataMember]
public List<User> Users
{
get
{
return _Users;
}
set
{
_Users = value;
}
}
public UserCollection()
{
_Users = new List<User>();
}
public void Add(User user)
{
_Users.Add(user);
}
public IEnumerator<User> GetEnumerator()
{
return _Users.GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return _Users.GetEnumerator();
}
}
Here is the code to serialize the UserCollection using DataContractSerializer.
public static string ToXmlString(object obj, bool omitXmlDeclaration)
{
DataContractSerializer dcSer = new DataContractSerializer(obj.GetType());
StringBuilder xmlString = new StringBuilder();
XmlWriterSettings settings = new XmlWriterSettings();
settings.OmitXmlDeclaration = omitXmlDeclaration;
XmlWriter writer = XmlWriter.Create(xmlString, settings);
dcSer.WriteObject(writer, obj);
writer.Close();
return xmlString.ToString();
}
The code below creates a collection of users and calls the above method which returns the XmlString.
User user = new User() { UserId = 101, UserName = "user101" };
_UserCollection.Add(user);
user = new User() { UserId = 102, UserName = "user102" };
_UserCollection.Add(user);
string userXml = DataContractSerializationHelper.ToXmlString(_UserCollection, false);
The Xml string would look like this:
This xml string can be sent as a sql parameter to a sql stored procedure to save multiple users at a single database call. In SQL SERVER 2000, we use the prepare document system stored procedure to get a document handle from the xml string. We then feed the document handle to the open xml function from which we can feed the xml data into a table. The code is shown below.
–Source: http://www.extremeexperts.com/SQL/Articles/OpenXML.aspx
— We get this by calling a stored procedure called sp_xml_preparedocument. We’ll talk more about this stored procedure in a moment.
–The RowPattern parameter specified which nodes we want OPENXML to process using XPath.
–The Flags parameter specifies the format of our results. The following values can be used:
–0 – Default value. Attribute centric mapping.
–1 – Use Attribute centric mapping.
–2 – Use element centric mapping.
–8 – Only unconsumed data should be copied to the overflow property @mp;xmltext.
DECLARE @DocHandle int, @AnswerSet VarChar(MAX)
CREATE TABLE #TempUsers
(
[UserId] Int,
[UserName] VarChar(300)
)
SET @AnswerSet = N’
<UserCollection xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns=http://schemas.datacontract.org/2004/07/Namsoft.Users.Model>
<Users>
<User><UserId>101</UserId><UserName>user101</UserName></User>
<User><UserId>102</UserId><UserName>user102</UserName></User>
</Users>
</UserCollection>’
— prepare the xml document
EXEC sp_xml_preparedocument @DocHandle OUTPUT, @AnswerSet, ‘<root xmlns:n="http://schemas.datacontract.org/2004/07/Namsoft.Users.Model"/>’
INSERT INTO #TempUsers ([UserId], [UserName])
SELECT *
FROM OPENXML (@DocHandle, ‘/n:UserCollection/n:Users/n:User’,2)
WITH (
[UserId] int ‘n:UserId’,
[UserName] varchar(300) ‘n:UserName’
)
— remove the xml document
EXEC sp_xml_removedocument @DocHandle
select * from #TempUsers
drop table #TempUsers
SQL Server 2005 has advanced support for Xml where it introduces the Xml DataType. More information about Xml DataTypes can be found on MSDN here. Here is a sample code to retrieve data from xml datatype.
DECLARE @AnswerSet Xml
CREATE TABLE #TempUsers
(
[UserId] Int,
[UserName] VarChar(300)
)
–SET @AnswerSet = N'<UserCollection xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/Namsoft.Users.Model"><Users><User><UserId>101</UserId><UserName>user101</UserName></User>
<User><UserId>102</UserId><UserName>user102</UserName></User></Users></UserCollection>’
SET @AnswerSet = N'<UserCollection><Users><User><UserId>101</UserId><UserName>user101</UserName></User><User><UserId>102</UserId><UserName>user102</UserName></User></Users>
</UserCollection>’
INSERT INTO #TempUsers([UserId], [UserName])
SELECT
T.c.value(‘./UserId[1]’,’int’),
T.c.value(‘./UserName[1]’,’varchar(300)’)
FROM @AnswerSet.nodes(‘/UserCollection/Users/User’) T(c)
select * from #TempUsers
drop table #TempUsers