advanced web development using c# david figge [email protected] session 2 last update: 1/12page...
TRANSCRIPT
Copyright (C) 2012 by David Figge. All Rights Reserved.
Advanced Web Development using C#
David [email protected]
Session 2
Last Update: 1/12 Page 1
Copyright (C) 2012 by David Figge. All Rights Reserved.
Advanced Web Development using C#
Check-In
Last Update: 1/12 Page 2
Copyright (C) 2012 by David Figge. All Rights Reserved.
Session 1: Introductions, Overview Gridviews Controls
Session 2: More on GridView Controls
Session 3: GridView Once Again ListViews
Session 4: The DetailsView and
FormView Caching
Session 5: File Streams Using XML
Session 6: User Controls
Session 7: CSS and Themes
Session 8: LINQ
Linq with DataSets Linq with Entities
Session 9: Deployment
Session 10: Final Lab
Class 2 Schedule
Last Update: 1/12 Page 3
Copyright (C) 2012 by David Figge. All Rights Reserved.
Advanced Web Development using C#
The List View
Last Update: 1/12 Page 4
Copyright (C) 2012 by David Figge. All Rights Reserved.
The ListView Control
The ListView's purpose is to assist you in creating lists You can think of it is a GridView – with rows
only, or an enhanced version of the Repeater control
You define the rows – using templates (which keeps it flexible)
And the ListView doesn't have the "drag-and-drop-and-it-works" functionality that GridViews have
Most developers with data to display start with the GridView, and move to the ListView if they need more specialized options
Last Update: 1/12 Page 5
Copyright (C) 2012 by David Figge. All Rights Reserved.
The ListView Control
Let's start by looking at the ListView in action We'll add a new Table View page to our
app We'll then list out the table numbers
and their capacities I know, pretty simple, but it will give you
the idea… Besides, they need to know that stuff in
restaurants .
Last Update: 1/12 Page 6
Copyright (C) 2012 by David Figge. All Rights Reserved.
The ListView Control
Last Update: 1/12
1. Create a new page for the web site2. Add a link in the Master page3. Drag a ListView onto the new page4. Link it to a new DataSource
1. SELECT * FROM [DiningTable]
5. Use the style links to view the different styles
6. Look at the source code generated
Page 7
You have lots of freedom to use any template/HTML code needed here. Lots of
flexibility is the value of ListView. Play with it a bit…
Copyright (C) 2012 by David Figge. All Rights Reserved.
The ListView Control
The Major Control Templates
Last Update: 1/12 Page 8
Template Description
ItemTemplate Sets the content of the Data Item
AlternatingItemTemplate If alternating (rows alternate), the above does odd, this does even rows
SelectedItemTemplate Sets content currently selected
EditItemTemplage Content when editing
InsertItemTemplate Content when inserting
LayoutTemplate Sets markup for wrapping content
GroupTemplate Sets markup for each group (if grouping)
Copyright (C) 2012 by David Figge. All Rights Reserved.
ListView Exercise
Last Update: 1/12
Create a new pagethat displays thenames andaddresses ofcustomers in"address label"format: Mabel Smith
127 Main StSeattle, WA 98103
Group them 3 across the top, paging as needed. You'll have to add some addresses to the table…
Page 9
45 Minutes
Copyright (C) 2012 by David Figge. All Rights Reserved.
DetailsView and FormView
As you know, we've spent quite a bit of time on displaying data This seems appropriate, as it's a major
purpose of a web application But before we delve into other
aspects, I want to touch on two other controls The DetailsView The FormView
Last Update: 1/12 Page 10
Copyright (C) 2012 by David Figge. All Rights Reserved.
DetailsView and FormView
The GridView – and to a lesser extent the ListView – are going to be your primary data display tools Both are very flexible, especially when
you bring templates into the picture But both of these focus on displaying
data by rows Sometimes you want to have one page
for each record That's where these two controls enter
in…
Last Update: 1/12 Page 11
Copyright (C) 2012 by David Figge. All Rights Reserved.
The DetailsView
The DetailsView control displays a single record at a time
It does so in a table, which each element (data column) being a row
Multiple records are accessed through page links at the bottom
It can auto-generate the rows, or (like the GridView) you can take control
The table uses the BoundField controls just like the GridView does
DetailsView supports delete, insert, and edit. This is even easier in the DetailsView than in the GridView.
The auto-generated code works well, and you can fine-tune it with templates as needed
Last Update: 1/12 Page 12
Copyright (C) 2012 by David Figge. All Rights Reserved.
The FormView
The FormView is similar to the DetailsView, but requires templates Given the assumption of templates, the
FormView becomes even more flexible that the DetailsView
You get to specify the templates you want for Viewing, Editing, Inserting, Footer, Header, and
more. The book covers these more in detail
As well as some more advanced uses of all these controls
I'm going to send you there for more information on these powerful tools.
Last Update: 1/12 Page 13
Copyright (C) 2012 by David Figge. All Rights Reserved.
Advanced Web Development using C#
Caching
Last Update: 1/12 Page 14
Copyright (C) 2012 by David Figge. All Rights Reserved.
Caching
Caching is a performance optimization that retains selected elements in memory, rather than recreating them every time.
There are two primary categories of caching Output caching – where rendered data is stored and
reused Data caching – where elements in your code are marked
to be saved and reused rather than recreated There are also two sub-categories of caching
Fragment caching – a type of output caching where only a portion of the rendered page is cached
Data Source Caching – using caching that's built in to DataSource controls that side-step repeated data queries
To begin with, let's look at the concept of caching and how that helps speed up systems…
Last Update: 1/12 Page 15
Copyright (C) 2012 by David Figge. All Rights Reserved.
What Is Caching?
Last Update: 1/12 Page 16
Let's start with a basic browser request for some data driven web page.So we start with the client (with the browser)…
The client requests a web page from the Web Server. This is where the ASP and code-behind pages live.
In order to display the data on the page, the web application makes a SQL request to the database server.
The database server retrieves the data from the database and returns it to the application on the web server.The Web application then uses that data to render the HTML page.
And the rendered data is returned to the browser on the client machine.
Any questions on how this process works?
So now we're going to replace our requesting client, and replace it with five clients. When you multiply the number of machines accessing the
system, you are assessing the system's scalability.So 5 machines hit the web server at about the same time…The data is retrieved for each client request…And the rendered pages are returned.So far so good. But as you can image, when we scale this scenario up to
hundreds of machines, lots of things are getting overworked.
So what if we look at the Web Server. If all the requests are looking at Dining Reservations, there's really no need to keep going to the database
server for data that hasn't really changed
So we tell the Web Server, "When someone requests a page, save a copy. If someone else requests the same page, give them the already generated
copy, saving the database access and the rendering.
Instantly, we've lightened the load on the Web Server (it only creates one page), and almost eliminated access to the database server (it's only called
to render the page the very first time).
This is the "big picture" concept of what caching is all about…
Does this concept make sense?
Copyright (C) 2012 by David Figge. All Rights Reserved.
Caching
This is an example of Output Caching – Saving the output from the Web Server and using it for subsequent requests
Data caching is the same concept, but for data elements (for example, images retrieved from the database)
Both of these caching techniques allow you to control how long the saved copy is valid
So, pictures of our customers (changes very little) could be cached for 24 hours before refreshing
But dining reservations (which change quickly in the evenings) might be cached for only 1 minute
For data, you can also say, "Cache this item until it changes", which gives you the ultimate flexibility
So let's delve just a little deeper and see how all this works…
Last Update: 1/12 Page 17
Copyright (C) 2012 by David Figge. All Rights Reserved.
Output Caching
Output caching is the easiest to implement (and often has the greatest impact) Once again this is caching a rendered page so
it can be used for subsequent requests Put, just below the <%@ Page… %>
<%@ OutputCache Duration="20" VaryByParam="None" %>
This says Cache the output Expire the cache (e.g. recreate the page) after 20
seconds 20 seconds may seem small, but if it's getting hundreds of
hits per second, it makes a difference!
Ignoring the VaryByParam part, does this make sense?
Last Update: 1/12 Page 18
Copyright (C) 2012 by David Figge. All Rights Reserved.
Output Caching
So VaryByParam comes into play when you have sites that are called with query strings http://catalog.bigcorp.com?prod=phones By specifying VaryByParam="prod", you can
cache a separate version for each "prod" requests
One for phones and another for music players To specify more than one, separate them with
semicolons VaryByParam="prod;color"
Note: this only works for server-based data You can't, for example, vary by session data or
cookies
Last Update: 1/12 Page 19
Copyright (C) 2012 by David Figge. All Rights Reserved.
Output Caching
The final option for output caching is to write your own function that returns a string
Specify VaryByCustom="…" This is in addition to the VaryByParam
Whatever string is in the VaryByCustom string is passed to the custom function GetVaryByCustomString
public override string GetVaryByCustomString(HttpContext context, string arg)
You can then (using the context) identify a "category" (you define this) that you want this request to be in
You return a unique string for each category For example: VaryByCustom="browser"
Your GetVaryByCustomString method – using "browser" as an indicator – can return the browser type being used, and cache a separate version for firefox, chrome, or IE.
Make sense?
Last Update: 1/12 Page 20
Copyright (C) 2012 by David Figge. All Rights Reserved.
Fragment Caching
Fragment caching is a way of caching only a part of the rendered page
To do this, you create a user control A user control is a collection of asp
controls…we'll do this later Within the user control, you put the
OutputCache directive (not in the page) This causes the control to be cached,
but not the entire page
Last Update: 1/12 Page 21
Copyright (C) 2012 by David Figge. All Rights Reserved.
Advanced Output Caching
You can also specify custom Cache Profiles within the web.config file You specify the profile name and the duration You can then specify the CacheProfile="…" in
the OutputCache directive This allows you to apply the same profile to
multiple elements in the site (and change them as a whole
While these are the major options… there are a couple more advanced output
caching techniques in the book that were not covering here…
Last Update: 1/12 Page 22
Copyright (C) 2012 by David Figge. All Rights Reserved.
Data Caching
This is the most flexible type of caching, but takes specific code to implement it
To use the Data Caching, you simply add objects that you want to cache to a global collection object "Cache"
e.g. Cache["Photo"] = myPhoto; Some basic tips about the global data cache
It's thread-safe No need to lock/unlock the cache when using it
Items are removed automatically If they expire or if memory gets low The means you MUST check for null when retrieving it!
It supports dependencies You can specify a resource (data table, file, etc.). If it
changes, the item is marked expired automaticallyLast Update: 1/12 Page 23
Copyright (C) 2012 by David Figge. All Rights Reserved.
Data Caching
When caching, you typically use Cache.Insert(key, value)
Inserts an object (value) into the cache retrievable by using the key
This is the same as Cache[key] = value Optional parameters (in order, all previous
parameters must be there): Dependencies – Changes to this resources causes
invalidation of cached element absoluteExpiration and SlidingExpiration – absolute is a
real DateTime, sliding is minutes-from-now Can only specify one. If using absolute, set sliding to
TimeSpan.Zero. If sliding, set absolute to DateTime.MaxValue Priority and onRemoveCallback – Sets the relative
priority (for removing objects when memory is full) and a callback (delegate called when discarded)
Last Update: 1/12 Page 24
Copyright (C) 2012 by David Figge. All Rights Reserved.
Code
Example Data Caching Example
private DataSet customerNames{ get { // Get the names from the cache DataSet names = Cache["CustomerNames"]; if (names == null) { names = GetNamesFromDatabase(); Cache.Insert("CustomerNames", names, null, DateTime.MaxValue, TimeSpan.FromMinutes(5)); } return names; }} ... DataSet ds = this.CustomerNames;
Last Update: 1/12 Page 25
A great way to set up data caching for an object is to create a property for the object. In this example, we're wanting to use (and cache) a
dataset of customer names.
The get method starts by trying to get the data from the cache. The times it will fail are 1) the first time, and 2) whenever the object expires.
If it fails, the cache returns null.
If it's not in the cache, we need to create it. So here we create the dataset.
We then insert it into the cache with the proper expiration settings.
Whether we created it or pulled it from the cache, in the end the property has it
and returns it to the requester.
When your program wants to use the dataset, it simply sets it through the property. The
complexity of caching and creating are hidden.
Does this allmake sense?
So this way you have the code that retrieves the data from the cache, the code the stores
the data in the cache, and the code responsible for creating the data object all in the same
place.
Copyright (C) 2012 by David Figge. All Rights Reserved.
Cache Dependencies
As we discussed, you can make cache expiration dependent upon changes in other objects.
To do this, you create a CacheDependency object Example:
CacheDependency pd = new CacheDependency(Server.MapPath("Products.xml"));Cache.Insert("Toaster",toaster,pd);
This makes the inserted item expire whenever "Products.xml" is modified
You can also create dependencies on other cached items Example:
String depKey = "Hello";CacheDependency cd = new CacheDependency(null,depKey);String key = " There";Cache.Insert("HiThere",key,cd);
Now when 'depKey' changes, key is expired You can also create aggregate dependencies
It's covered in the book, along with some lesser-used caching options
Last Update: 1/12 Page 26
Copyright (C) 2012 by David Figge. All Rights Reserved.
Caching Summary
Things to keep in mind about caching Caching is an optimization
Address it as you start planning your deployment After you have an idea of where the bottlenecks are…
Look for objects that take a while to produce and look to cache those first
Often, even for a short time, you see advantages This is why output (page) caching make sense
Pages often take a long time to produce, so are ripe candidates for caching
Once you've identified an object, look seriously at how long it can be cached
Resist the temptation to make everything short You can often live with "not quite up to date" data for longer
than you think
Last Update: 1/12 Page 27
Questionson caching?
Copyright (C) 2012 by David Figge. All Rights Reserved.
Advanced Web Development using C#
File and File Streams
Last Update: 1/12 Page 28
Copyright (C) 2012 by David Figge. All Rights Reserved.
Directory and File Classes
There are two ways to access information about files and directories
Directory and File These are static classes, and are used for quick access to
files or directories DriveInfo, DirectoryInfo, and FileInfo
These are used to retrieve similar information, but are associated with a specific object
The Directory and File work well for one-time quick tasks (e.g. creating a directory)
The others work better when you're performing a series of tasks on the same object
This way things like security checks are done as you create the object, rather than every time you use it
Let's look at the major tasks and methods in both systems…
Last Update: 1/12 Page 29
Copyright (C) 2012 by David Figge. All Rights Reserved.
Major DirectoryTasks
Last Update: 1/12 Page 30
Task Directory Class DirectoryInfo class
Create a directory Directory.CreateDirectory(path) dir.CreateSubdirectory()
Delete a directory Directory.Delete(path) dir.Delete()
Check for existance Directory.Exists dir.Exists
Get array of directory names
Directory.GetDirectories(path) dir.GetDirectories()
Get array of files Directory.GetFiles(path) dir.GetFiles()
Get drives Directory.GetLogicalDrives() ---
Get parent dir Directory.GetParent(path) dir.Parent
Get current dir Directory.GetCurrentDirectory() ---
Set current dir Directory.SetCurrentDirectory() ---
Move dir Directory.Move(path,path) dir.MoveTo(path)
Copyright (C) 2012 by David Figge. All Rights Reserved.
Major File Tasks
Last Update: 1/12 Page 31
Task File Class FileInfo class
Create a file File.Create(path), file.CreateText(path)
file.Create()file.CreateText()
Copy a file File.Copy(path,path) file.CopyTo(path)
Move a file File.Move(path,path) file.MoveTo(path)
Delete a file File.Delete(path) file.Delete
Get attributes File.GetAttributes(path) file.Attributes()
Set attributes File.SetAttributes(path…) file.Attributes()
Get parent dir --- file.DirectoryName
Get file length --- file.Length
Copyright (C) 2012 by David Figge. All Rights Reserved.
The Path Class
If you end up manipulating directory and file paths, consider using the Path class It is a static class that has some helper functions
to assist in creating, modifying, and using paths, including
Combine – Combine directory and file into path ChangeExtension GetDirectoryName – Full directory list GetFileName – Returns filename from path GetFilenameWithoutExtension GetFullPath – like c:\windows\notepad.exe GetPathRoot – From C:\windows\notepad.exe: = c:\ HasExtension – True if has extension, false if not IsPathRooted – True if from root, false if relative
Last Update: 1/12 Page 32
Copyright (C) 2012 by David Figge. All Rights Reserved.
B4 A8 C3 F2 38 44 D3
Streams
Last Update: 1/12 Page 33
The C# I/O system is based on streams. A stream is simply a series of bytes. So when you work with steams, you work with Byte arrays.
The FileStream is a stream that is connected to a file on the disk. So it allows you to read and write using Byte arrays.
(This is not very convenient)
So when we want to work with something other that Byte arrays – like always – we wrap the FileStream in class that translates it to something
more useful.
So if, say, we want to read text files, we wrap the FileStream in a StreamReader object. StreamWriters allow us to write text to the file.
If, on the other hand, we want to write binary data, we use a BinaryReader/Writer. These know how to read/write ints, floats, strings,
etc.Let's look at some simple examples of reading and writing a text file…
Four score and 7 years ago…27,3.14,"Smith, Bob" FileStreamStreamReaderBinaryReader
Copyright (C) 2012 by David Figge. All Rights Reserved.
Code
Example Stream Examples
FileStream fs = new FileStream("textFile", FileMode.OpenOrCreate);StreamWriter writer = new StreamWriter(fs);for (int x = 0; x < 25; x++) writer.WriteLine(x.ToString());writer.Close();fs.Close();
StreamReader reader = new StreamReader("textFile");StringBuilder contents = new StringBuilder("");string line;while ((line = reader.ReadLine()) != null) contents.Append(line + ",");reader.Close();
using (StreamReader reader = new StreamReader("textFile")){ String contents = reader.ReadToEnd();}
Last Update: 1/12 Page 34
Let's start with the basics: writing a series of lines to a text file.
We start by creating a FileStream object. Because FileStreams only work with bytes – and we want to work with text – we'll wrap it in a StreamWriter.
So here we're doing that. Notice that it takes the base FileStream object as a
parameter in the constructor.
Now we write 25 lines to the text file. We do that using the
WriteLine method of the writer object. Each 'wrapper' object has the ability to work with its
data types, so (for example) BinaryWriters can write ints,
floats, etc.
When we're all done, we make sure to close the writer (most recently opened),
then the filestream.
Questions so far?
Okay, so let's take a look at reading in that data. Here we create a StreamReader. Notice
that there are many constructors to a StreamReader. This one takes a filespec, and will create the underlying FileStream object
for us and open the file for reading.We're going to read in several lines (one at a time), so we'll put the results into a
StringBuilder object
Here we read in a line of text using the ReadLine method within the
StreamReader object. ReadLine returns null when it reaches the end of the file.
For each line, we add it on to the StringBuilder, and when we're done we
close.
Is this code making sense, too?
Finally, I want to bring up even more flexibility within the streams system.
If you recall, there is a block that starts with a using statement. Anyone
remember what it does?
It allows you to specify a block where you're using an object. When the block goes out of scope (either normally or by
an exception), the dispose method is automatically called.
More importantly – with objects that support it – you can create objects that sort of clean up after themselves when
you're done with the block
Well, Stream objects support that. So these 2 code lines do what those six
lines did above.
Here we create the StreamReader object in the using clause. This opens
the file for read using the StreamReader
We then call the ReadToEnd method, which reads from the file until it
reaches the end of the file (a very convenient method!).
When we reach the end brace of the using statement, the reader automatically closes the file.
Pretty convenient, huh?
Questions onany of this?
Copyright (C) 2012 by David Figge. All Rights Reserved.
Customer Email Exercise
Last Update: 1/12
It's time for you to playwith this a bit…
You're going to addfunctionality to generatean email (in a text file)that can be sent to acustomer to remind themof their reservations.
You'll need to use whatyou've learned to…
Add a command button to each row in the reservations GridView labeled Email
When the button is pressed Create a file called "Reminder Email.txt" that has the above text
customized for the customer in the row Good luck!
Page 35
To: [email protected]: Your Reservation at Le RestaurantDear John,
This email is a reminder that you havea dinner reservation at our restaurantfor 8:30 tomorrow.
See you then, the Le Restaurant staff
50 Minutes
Copyright (C) 2012 by David Figge. All Rights Reserved.
Advanced Web Development using C#
Using XML
Last Update: 1/12 Page 36
Copyright (C) 2012 by David Figge. All Rights Reserved.
XML Review
XML is a ubiquitous way to transfer data, and is an integral part of C#
XML has several advantages:1. It's plain text: human readable, easily written and
read by programs2. It's flexible: you make up the structure as you need
it3. It's an industry standard: there are many tools to
create, read, and manipulate data within XML files Over the next several slides we'll see the
pieces that C# provides in order to create, read, and use XML files.
Let's start with a simple review by looking at a typical XML file…
Last Update: 1/12 Page 37
Copyright (C) 2012 by David Figge. All Rights Reserved.
Code
Example XML Example<?xml version="1.0" encoding=“UTF-8" ?><!-- Breakfast Menu --><breakfast_menu xmlns="http://lerestaurant.com"> <food number="1"> <name>Belgian Waffles</name> <price>$5.95</price> <description>two of our famous Belgian Waffles with plenty of real maple syrup</description> <calories>650</calories> </food> <food number="2"> <name>Strawberry Belgian Waffles</name> <price>$7.95</price> <description>light Belgian waffles covered with strawberries and whipped cream</description> <calories>900</calories> </food> <food number="3"> <name>Berry-Berry Belgian Waffles</name> <price>$8.95</price> <description>light Belgian waffles covered with fresh berries and whipped cream</description> <calories>900</calories> </food> <food number="4"> <name>French Toast</name> <price>$4.50</price> <description>thick slices made from our homemade sourdough bread</description> <calories>600</calories> </food> <food number="5"> <name>Homestyle Breakfast</name> <price>$6.95</price> <description>two eggs, bacon or sausage, toast, and our ever-popular hash browns</description> <calories>950</calories> </food></breakfast_menu>
Last Update: 1/12 Page 38
This first line is technically optional, but is usually there. It tells the
‘version’ of XML that is being used. Version 1.0 corresponds to the W3C
specification for XML 1.0.
It also specifies that we’re using UTF-8
encoding (8 bit Unicode characters)
Comments in XML start with <!– and end with -->.
Each XML document has one (and only one) root element, in
this case breakfast_menu.
For every element/tag, there is a closing element/tag (the name
with a / before it)
In XML, the tags are made up by the writer. This is what makes it so
flexible. When used as input to a program, the program must
understand what the tags mean (so coordination is needed).XML documents have no
required layout format, but this example is typical of how most XML documents are made and
displayed. Like C#, carriage returns and tabs are optional (but you should use them).
This XML document contains a collection of food offerings. Multiple
food tags are stored in the breakfast_menu. Each food block starts
with <food> and ends with </food>
There are two ways to define information for an element. The name tag defines a sub-
element of food, and (in this case) contains the text Belgian Waffles.
The other way is to specify an Attribute, which is within the
Element tag like this.
You can specify all elements as Attributes instead (they are seen as the same). For example
<food number=“1” name=“Belgian Waffle” … />
The /> can close a tag when there are no sub-elements.
Questions on XML layout?
Finally, let's talk about this portion of the root tag: xmlns. This defines a namespace, and
typically has a server address for the company. The idea is to keep it unique. If any other
"breakfast_menus" were processed at the same time, this would differentiate them.
Copyright (C) 2012 by David Figge. All Rights Reserved.
XML Files
XML files are expected to follow several rules. These are stricter rules that applies to (for example) HTML files
Primarily, XML files are held to the "well formed" standard, which means: Every element has a start and end tag Empty cells end with /> Elements can be nested, but are fully enclosed
by their parent (no unclosed tags at the end of an element)
There is 1 (and only 1) root element Comments start with <!- - and end with - ->.
Comments cannot be inside tags.Last Update: 1/12 Page 39
Copyright (C) 2012 by David Figge. All Rights Reserved.
XML Schema Documents
In a database, you use a schema to define the elements within the tables
In an xml file, you can also create a schema document to define the contents of the XML file This way, a receiving program could
know the xml layout Not surprisingly, these documents
are stored in XML format Let's see an example…
Last Update: 1/12 Page 40
Copyright (C) 2012 by David Figge. All Rights Reserved.
Code
Example XML Schema Example
<?xml version="1.0" encoding="ISO-8859-1" ?><xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:element name="breakfast_menu"> <xs:complexType> <xs:sequence> <xs:element name="food" type="foodType" maxOccurs="unbounded" /> </xs:sequence> </xs:complexType> </xs:element>
<xs:complexType name="foodType"> <xs:sequence> <xs:attribute name="number" type="xs:decimal" use="required"/> <xs:element name="name" type="xs:string"/> <xs:element name="price" type="xs:decimal"/> <xs:element name="description" type="xs:string"/> <xs:element name="calories" type="xs:decimal"/> </xs:sequence> </xs:complexType></xs:schema>
Last Update: 1/12 Page 41
Here we say the primary element in this xml file is
breakfast_menuIt is a complex type (meaning
more than one intrinsic element).
Breakfast_menu contains a sequence of elements named "food", which is defined below in the "foodType" definition, and there's no limit on how
many food elements can be in the XML file.
The foodType complex type is defined here.
It contains one attribute and 4 elements as defined here.
These were all simple data types (strings and decimals). If we had
any more sub-elements, we could define more
complexTypes. XML Schema definitions help in processing the XML file so that the processing routine can find
out at run-time the layout of the XML file. You don't need
the schema if you have a processing routine that is
specifically designed to work with your XML file layout.
Copyright (C) 2012 by David Figge. All Rights Reserved.
Reading and Writing XML Documents
Functionality Method Comments
Write whole document
doc.Save Saves an XMLDocument object as an XML file (example coming)
Read whole document
doc.Load Loads an XML file into an XMLDocument object
Write line-by-line writer.WriteStartDocument()writer.WriteComment()writer.WriteStartElement()writer.WriteElementString()writer.WriteEndElement()
Use XMLTextWriter to write each line of the XML file. Methods allow you to add any part of XML file by method calls.
Read line-by-line reader.readStartElement()reader.readElementString()reader.readEndElement()
Use XMLTextReader to read in elements and values
Read Line-by-line, unknown structure
reader.Read() Use XMLTextReader to read in nodes, elements, and text using reader.NodeType (XmlNodeType.Element, XmlNodeType.Text, etc.)
Last Update: 1/12 Page 42
Copyright (C) 2012 by David Figge. All Rights Reserved.
XMLDocument
The XMLDocument object allows you to read an XML document into a tree structure of XMLNodes (each of which may have XMLNodes themselves
Use doc.Load() to read in the entire XML document
You can then use the collection(s) of XMLNodes to navigate through the hierarchy
In fact, a really easy way to create an XML file is to create an XMLDocument object, then use the .Save method to write it to a file
Let's look at an example…
Last Update: 1/12 Page 43
Copyright (C) 2012 by David Figge. All Rights Reserved.
Code
Example Creating and Saving an XML File
XMLDocument doc = new XMLDocument( new XDeclaration("1.0", "utf-8", "yes"), new XComment("Created: " + DateTime.Now.ToString()), new XElement("breakfast_menu", new XElement("food", new XAttribute("number","1"), new XElement("name","Belgian Waffles"), new XElement("Price","$5.95"), new XElement("description","two of our famous..."), new XElement("calories","650") ), new XElement("food", new XAttribute("number","2"), ... ), ... ));doc.Save("Breakfast_Menu.xml");
Last Update: 1/12 Page 44
Copyright (C) 2012 by David Figge. All Rights Reserved.
XPath
XPath (and it's navigation tool XPathNavigator) is a similar tool to XmlDocument, but uses a cursor-based approach
So – unlike XmlDocument which uses a tree-like structure – XPathNavigator goes through the elements one at a time.
More info on XPath, XPathNavigator, and XmlDocument are in the book
Last Update: 1/12 Page 45
Copyright (C) 2012 by David Figge. All Rights Reserved.
Transforming XML Documents
A common requirement with Web sites is the need to translate an XML file contents into something usable for a Web page
You can, of course, use XmlDocument and/or XPathNavigator to go through the document in code
But a very useful (and more common) way is to translate the XML file into HTML using an Extensible Stylesheet Language Translator file, or XSLT.
Last Update: 1/12 Page 46
Copyright (C) 2012 by David Figge. All Rights Reserved.
XSLT
XSLT is a language unto itself, with loops and other such constructs As such, it's beyond the scope of this
class to teach you XSLT – which could be a class all by itself
However, you don't need to take another class just to get the gist of how it works.
We'll investigate this by doing an exercise together
Last Update: 1/12 Page 47
Copyright (C) 2012 by David Figge. All Rights Reserved.
Adding a Dinner Menu
Last Update: 1/12
We're going to work together to add a Dinner Menu page to our project The dinner menu will be
Read in from an XML file Translated into HTML by an XSLT file Displayed in our application by an XML control
Start by getting the menuItems.zip file This contains the XML file, the XSLT file,
and the images that will be displayed
Page 48
Copyright (C) 2012 by David Figge. All Rights Reserved.
Adding a Dinner Menu
Last Update: 1/12
Uncompress the Zip file and add each element (pictures too) to your project Put them in the main folder (where the
aspx files are) Add them to Solution Explorer with
Project/Add/New Item… This helps VS rebuild properly when files
change We'll take a look at the XML and XSLT
files in a second, but first let's get them working on the site…
Page 49
Copyright (C) 2012 by David Figge. All Rights Reserved.
Adding a Dinner Menu
Last Update: 1/12
Add a new Web Page (with Master) Call it Menu.aspx, linked to Site.Master Add a new menu item to Site.Master labeled
"Today's Menu" linking to our new page On the new page
In the Main Content section Add the text "Today's Menu"
<h1 class="style1">Today's Menu</h1>
An an XML control Set the DocumentSource property to "~/menu.xml" Set the TransformSource property to "~/menu.xslt"
Page 50
Copyright (C) 2012 by David Figge. All Rights Reserved.
Adding a Dinner Menu
Last Update: 1/12
Your "Today's Menu" item should nowwork
Let's take a look atthe XML and XSLTfiles…
Page 51
Copyright (C) 2012 by David Figge. All Rights Reserved.
Advanced Web Development using C#
End of Session 2
Last Update: 1/12 Page 52