|
XML Serialization广告 XML Serialization In this article, we're going to be taking a look at XML serialization. This is the process of taking an object, turning it into an XML document and either storing it for later use, or moving it to another part of the network for use elsewhere. XML serialization in .NET works by examining the properties on a class that are flagged as read/write. Whenever it comes across one of these properties, it takes the current value and inserts in into the XML document. De-serialization is, as I'm sure you've guessed, the opposite of this process. As you're no doubt aware, .NET makes fairly gratuitous use of XML. What we can do with the XML serialization in .NET is turn any object into a block of XML, ready to send down a stream. As you learn more about .NET, you'll discover that the stream metaphor comes up quite regularly. For example, to write a file to a disk, you open a file stream and to send bytes to another computer on the network, you open a network stream. This abstraction is neat and is common to a lot of aspects of .NET development - once you know how to do it one way, learning how to do it another, related way is very easy. XML Serialization in the .NET
Framework In most cases, you won't have to make any changes to the object you want to serialize. XmlSerializer works by examining the properties on the object and assumes that any read/write property should be included in the serialization. It will then call these properties as if it were a typical consumer. For example, if your object implements a read/write property called Name, XmlSerializer will ask for that property and insert the return value into the XML block. When XmlSerializer is asked to build an object from a block of XML, it will take the value stored in the XML block and set the property to the value. (This is done through reflection, which we'll talk about in a moment). On first glance, this seems like a kludge. I, as a fairly typical developer, was not tremendously comfortable with this approach at first glance. I would prefer it if, for example, XmlSerializer called a method on an interface asking me to supply the information I want inserted into the XML. In fact, this is exactly the way the ISerializable interface and the System.Runtime.Serialization namespace works. However, implementing ISerializable is non-trivial, whereas using XmlSerializer is very trivial to implement. By the time I'd finished taking a good long look at XML serialization, I realized it is tremendously powerful and well worth using. For experienced developers - don't worry about the lack of control. XML serialization provides a quick and dirty way of shoving objects down streams and pulling them out again. Reflection The XmlSerializer simply calls GetProperties to return an array of PropertyInfo objects, each one describing a property on an object. If the property is read/write, it will be included in the serialization. Although ASPToday will be running an article on reflection in the near future, there is some good reading out there if you're interested. Of course, you can also try out reflection yourself using the ClsView sample included with the Framework SDK. One part of reflection that hurts my head when I think about it is emitting. This lets you build classes from scratch at runtime, and use them in your application as if they were normal classes. Testing Serialization To show us what's going on, our project is going to create a form containing a text area field. We're going to use an object called Book that contains the name, ISBN number and list of authors for the book. This field will be populated with the XML generated by XmlSerializer. We can then change the XML and create a new object from the XML block. (For example, we could change the title of the book from Beginning E-commerce to VB .NET Programming with the Public Beta). Once we have the new object, we'll use a simple server-side control to render the results to the user. Creating the Form <%@ Page Language="vb" AutoEventWireup="false"
Codebehind="WebForm1.vb"
<form id="WebForm1" method="post"
runat="server"> </body></html> You'll notice that we've set the id attribute of the textarea element to xmlarea. This will let us manipulate the element from our VB code. In particular, we want to use its Value property to get and set the text contained within the element. If we run the page now, this is what we get: One problem with the VS .NET IDE: although we've added the text area field to the page, sometimes a reference to xmlarea won't be added to the WebForm1 class definition. Without this, we won't be able to refer to the field as we are processing, hence we won't be able to get or set its value. If you open the code for WebForm1.vb, you should see a line like this: Public Class WebForm1 If the line is not there, add it yourself! Creating the Book class Imports System Public Class Book Private m_Name As String Public Property Name() As String Public Property ISBN() As String Handling PreRender Of course, we can't use XmlSerializer until we've added a reference to it in our project. To do this, in Solution Explorer, right click References and select Add Reference. Scroll down until you find System.Xml.Serialization.dll. Click Select, then OK. Before you can use the object, we need to include a reference to it at the top of WebForm1.vb: Imports System Open WebForm1.vb in the IDE and use the object drop down in the top-left to select the WebForm1 instance, and select PreRender from the methods list on the right. Add this code to check to see if we've already got a value for xmlarea: Public Sub WebForm1_PreRender(ByVal sender As Object, _ ' if we don't already have a value, create a default
book... If the form has been submitted, xmlarea will have a value. Specifically, it will contain whatever the user wanted to add to our field. Next, we need to create an instance of a Book object and set the properties: ' create an instance of a book... The next thing we need to get hold of is a System.IO.TextWriter that XmlSerializer will send the data to. A TextWriter is usually used to provide access to a stream of data, such as a file on disk or network connection. In our case, we're going to use a System.IO.StringWriter object. This is a TextWriter object that sits on top of a string, so whenever new data is added it is just concatenated onto the end of the data it already has. ' create a new string writer... Next we create the XmlSerializer object itself. This requires the Type object of the thing we're trying to serialize. Once we have that, we ask it to serialize the object to the StringWriter object: ' create a serializer... Finally, we can use the ToString method of the StringWriter to get hold of the XML block. We then set the value of the text area element to be this string: ' set the value in the form... End If End Sub If we run the code now, we can see the XML serialization string for the default book object: Turning XML back into an object To display the details of the object to the user, we're going to use an ASP .NET server-side control. This control will have a property called Book that we will use to tell the control which book we want to render. Create a new class called BookView and add this code: Imports System Namespace Controls Public Class BookView ' need somewhere to store the book... Public Property Book() As Book End Class End Namespace The Inherits Control directive tells VB to inherit the class from the System.Web.UI.Control object. This provides the control with the various methods needed to support the control from within an ASPX page. Likewise, before we can use a control, it has to be placed into a namespace. I've used the name Controls, meaning that this class is technically known as Serialization.Controls.Bookview. To make the control do something, we need to override the Render method. If we don't have a Book object to render, we just want to tell the user we have nothing to do: Protected Overrides Sub Render(ByVal writer As System.Web.UI.HtmlTextWriter) ' do we have a book? ' render something... Else If we do have a book, we want to render everything we know: ' draw the name of the book... End If End Sub Adding the control to the ASPX
page <%@ Page Language="vb" AutoEventWireup="false"
Codebehind="WebForm1.vb" Inherits="Serialization.WebForm1"%> The TagPrefix attribute tells ASP .NET what namespace a particular server-side control is in. To add our control to our form, we use this prefix coupled with the name of the class itself: <form id="WebForm1" method="post"
runat="server"> <mycontrols:bookview runat="server" id="bookview"></mycontrols:bookview> Again, notice how we've given the BookView control a name using the ID attribute. This will let us refer to the control from within the VB code by name, much like we do with xmlarea. The VS .NET IDE may have had an issue adding a definition to bookview to WebForm1. Make sure that this line exists against the class. If it's missing, add it manually: Public Class WebForm1 Processing the XML First off then, we have to look to see if the page has been posted back. If it has, we can do our processing. Firstly, we create a new StringReader and tell it to use the value of xmlarea as its source: Protected Sub WebForm1_Load(ByVal Sender As System.Object,
_ Else ' try and turn the xml back into an object... Now, like before, we create an instance of an XmlSerializer and tell it what type of object we want. (Here, to get the type, I've created an instance of a Book object and used GetType. XmlSerializer won't set the properties on this particular object - this object exists solely to provide type information). ' create a serializer... Finally, we use a Try.Catch block around Deserialize. There's no guarantee the user will give us a valid block of XML, so we have make sure nothing goes wrong. ' try and read it... ' turn it into a book... Catch End Try End If End Sub To test this out, we run the project and change the XML that gets created by default. When we click Turn XML into an object, the new Book object we get will contain altered data: Using Arrays This illustrates the big drawback to XML serialization - there are quite a few things it can't handle. In short, XML Serialization can only handle very basic data types, thinks like numbers, strings and other objects that have read/write properties that use only those basic types. One of the ways that ASP developers are used to moving chunks of data around is using things like dictionaries and collections. XML serialization cannot handle these, but it can handle arrays. Paradoxically, ASP developers aren't very comfortable with moving arrays around because previous versions of VB weren't too good at handling these. Internally, we can store data however we want, and .NET provides plenty of useful objects for handling lists of data. However, to serialize that information into and from XML we need to transform the lists into an array. The "Author" object Imports System Public Class Author Private m_Name As String Public Property Name () As String End Class To hold a list of authors on the Book object, we need to create some form of list. We'll use a Hashtable, so add this code to the Book class definition: Private m_Name As String To add a new author to the list, we'll create the AddAuthor method. This method will create a new Author object, and add it to our hash table. ' a method to add an author... ' create a new author... ' add it to the collection... End Function Now when we create our default object, we need to add an author. We can do this by altering the WebForm1_PreRender handler: ' create an instance of a book... As we said, in order to serialize the hash table, we need to convert it to an array. Here's the implementation of the Authors property that converts the hash table to an array of Author objects and vice versa: Public Property Authors() As Author() ' create a new author array... ' return the array... End Get ' reset the authors we've already got (i.e. what ' go through the authors we have... End Set Now if we try and run the project, we'll notice the list of authors is added to the XML block: To see whether the XML can be serialized back into an object, we need to change our BookView control to render a list of authors. Add this code to the Render event handler: ' draw the name of the book... ' loop through the authors... Now when we change the XML to include a new author and click Turn XML into an object, we get this: Summary 如果您希望与本文章的作者或其所在机构,进一步交流,请联系:畅享网 姜小姐 jill.jiang@amt.com.cn | 021-51096826-112 | 在线联系 |
CIO职场,强者生存?在2008年,我们将继续看到CIO向商业运营方向发展。与此同时,我们也会看到商业管理人员将与技术管理人员一起竞争CIO岗位。 IT领导者的就职机会虽有不少,但其难度将会大幅提高。2…… 防震减灾,IT当关今天,任何的防震救灾体系,都离不开IT技术。地震观测台是数字化的,震害防御需要对以往的地震信息进行数据分析,应急救援要需要现代多样化的通讯技术。如果说,在许多行业,信息技术还只是一…… |
|
|