More Visual Studio

bevyquixoticΑσφάλεια

3 Νοε 2013 (πριν από 3 χρόνια και 7 μήνες)

136 εμφανίσεις

Web Services

© 2012

University
of

Greenwich

1

More Visual Studio

Data Binding and Web Services

Dr Kevin McManus

http://staffweb.cms.gre.ac.uk/~mk05/web/dotnet/#lecture3

Web Services

© 2012

University
of

Greenwich

2

Data Binding


Data binding in .NET is much improved on
previous Microsoft implementations


Use data binding to make a link between the
user interface and the data model



Create a C# Web Site project


Bind a property and a method to GUI
components


DataBind()

Web Services

© 2012

University
of

Greenwich

3

Data Binding

add a calendar, three
buttons and a label to
the design surface

Web Services

© 2012

University
of

Greenwich

4

Data Binding

add a level 1 header

give the components sensible
names and values
-

this can be
done using the property
browser in design view

add some executable
code to the header,
calendar and label

Web Services

© 2012

University
of

Greenwich

5

Data Binding

<body>


<h1>Airline:
<%# airline %>
</h1>


<form id="form1" runat="server">


<div>


<asp:Calendar ID="
calDepart
" runat="server"



SelectedDate="
<%# setCalendar() %>
"></asp:Calendar>


<br />


&nbsp;</div>


<asp:Button ID="
btnToday
" runat="server" Text="Today" />


&nbsp;


<asp:Button ID="
btnTomorrow
" runat="server" Text="Tomorrow" />


&nbsp;


<asp:Button ID="
btnNextWeek
" runat="server" Text="Next Week" /><br />


<br />


<asp:Label ID="
lblDepartDate
" runat="server" Text="Departure date">



<%# calDepart.SelectedDate.ToShortDateString() %>


</asp:Label>


</form>

</body>

add code to the code behind module to handle all this

double click the GUI widgets to get the event handlers

property

methods

Web Services

© 2012

University
of

Greenwich

6

Data Binding

protected int futureDay = 0;


public string airline

{


get


{



return "Acme Airways";


}

}


public DateTime setCalendar()

{


return DateTime.Today.AddDays(futureDay);

}


private void Page_Load(object sender, System.EventArgs e)

{


DataBind();

}


long winded property
constructor

method to set
the calendar

data bind the
page on load

Web Services

© 2012

University
of

Greenwich

7

Data Binding

private void btnToday_Click(object sender, System.EventArgs e)

{




futureDay = 0;




DataBind();



}


private void btnTomorrow_Click(object sender, System.EventArgs e)

{




futureDay = 1;




DataBind();



}


private void btnNextWeek_Click(object sender, System.EventArgs e)

{




futureDay = 7;




DataBind();



}


private void calDepart_SelectionChanged(object sender, System.EventArgs e)

{




lblDepartDate.DataBind();

}

data bind
everything

Web Services

© 2012

University
of

Greenwich

8

Data Binding

couldn't resist correcting the
markup for this form

gotta have a green bar from
the W3

note how this is all
postback driven

every mouse click fires
an HTTP request

Web Services

© 2012

University
of

Greenwich

9

Connecting to Databases


Visual Studio integrates with SQL Server


edit SQL Server data directly in VS.NET


execute SQL statements


VS Server Explorer provides easy connection to
databases


View
-
> Server Explorer


Data binding links controls on the user interface
to data stored in SQL Server


now largely automated in VS05

Web Services

© 2012

University
of

Greenwich

10

Binding to a Datagrid


Create a new C# Web Application project


give it a meaningful name


give the web form a meaningful name


Use the Server Explorer to locate your
SQL Server database



sql
-
server.cms.gre.ac.uk

Web Services

© 2012

University
of

Greenwich

11

Binding to a Datagrid


Create a new C# Web
Application project


give it a meaningful name


give the web form a
meaningful name


Use the Server Explorer
to locate your SQL Server
database



sql
-
server.cms.gre.ac.uk


Web Services

© 2012

University
of

Greenwich

12

Binding to a Datagrid

drag a
table onto
the design
surface

automatically creates
a datagrid and invites
you to configure it

Web Services

© 2012

University
of

Greenwich

13

Binding to a Datagrid

choose from some
imaginatively named
preset styles

configure what you
want in the grid

Web Services

© 2012

University
of

Greenwich

14

Telephone Directory


In ye olden days you had to do a lot of this stuff
manually


dive in and data bind stuff


All now tooled up and automated


Repeat the exercise as a Web Service


Right click the project in the solution explorer
and add a web service


rename it
phoneBook.asmx

Web Services

© 2012

University
of

Greenwich

15

Add a web service to
the project

Telephone Directory Web Service

Give it a
sensible name

Web Services

© 2012

University
of

Greenwich

16

Telephone Directory Web Service

using

System.Data;

using

System.Data.SqlClient;



[
WebMethod
]


public

DataSet

getDirectorySql()


{


// Open a connection the the SQL Server


SqlConnection

sqlConn =
new

SqlConnection
();


sqlConn.ConnectionString =


"server=sql
-
server;integrated security=SSPI;database=mk05"
;



// Create a SQL query


SqlCommand

sqlCmd = sqlConn.CreateCommand();


sqlCmd.CommandType =
CommandTyp
e.Text;


sqlCmd.CommandText =
"SELECT fname, sname, phone, loc FROM phoneBook"
;



// Set up data adapter and fill the dataset


SqlDataAdapter

dataAdptr =
new

SqlDataAdapter
();


dataAdptr.SelectCommand = sqlCmd;


DataSet

dsStaff =
new

DataSet
(
"directory"
);


dataAdptr.Fill(dsStaff,
"staff"
);



// And return it to the client


return

dsStaff;


}

connection string
provided by our sysops

add data handling
system libraries

Web Services

© 2012

University
of

Greenwich

17

the DataSet is returned
in XML format


with schema included

Web Services

© 2012

University
of

Greenwich

18

.NET XML Containers


Three XML document stores each with different features


XmlDocument


the primary document store


supports W3C standards for XML document (DOM), plus useful
additional features that make it easier to access the contents


XmlDataDocument


provides a bridge between XML and relational data by allowing the
content to be accessed as a DataSet instance as well as a standard
XML document


XPathDocument.


fast and efficient document store designed to be accessed only using
XPath methods and the XPathNavigator


XPathNavigator can be used over any of the three document stores

Web Services

© 2012

University
of

Greenwich

19

Telephone Directory Web Service


Re
-
write the web service to return an
XmlDocument


instead of a data set


Convert the data set read from SQL Server into
a string


Load the string into an XmlDocument



Web Services

Telephone Directory Web Service

using

System.Xml;



[
WebMethod
]


public

XmlDocument

getDirectoryDom()


{


// Open a connection the the SQL Server


SqlConnection

sqlConn =
new

SqlConnection
();


sqlConn.ConnectionString =


"server=sql
-
server;integrated security=SSPI;database=mk05"
;



// Create a SQL query


SqlCommand

sqlCmd = sqlConn.CreateCommand();


sqlCmd.CommandType = CommandType.Text;


sqlCmd.CommandText =
"SELECT fname, sname, phone, loc FROM phoneBook"
;



// Set up data adapter and fill the dataset


SqlDataAdapter

dataAdptr =
new

SqlDataAdapter
();


dataAdptr.SelectCommand = sqlCmd;


DataSet

dsStaff =
new

DataSet
(
"directory"
);


dataAdptr.Fill(dsStaff,
"staff"
);



// Create an XML document and read the data set into it


XmlDocument

xmlDom =
new

XmlDocument
();


xmlDom.LoadXml(dsStaff.GetXml());


return

xmlDom;


}

get the data set as a
string and then load it
into an XML document

add XML
system library

this is all the
same as before

Web Services

© 2012

University
of

Greenwich

21

clean XML returned


we could easily
manipulate this XML
further using DOM
programming

Web Services

© 2012

University
of

Greenwich

22

Telephone Directory Web Service


Microsoft Access database uses an OLEDB JET
connection string


System.Data.OleDb


old fashioned


insecure


popular


Next example uses DOM to read data from
Access in XML format



Web Services

© 2012

University
of

Greenwich

23

using

System.Data.OleDb



[
WebMethod
]


public

XmlDocument

getDirectoryOledb()


{


// Open OLEDB connection to Access database


OleDbConnection

DBconnection =
new

OleDbConnection


(
"PROVIDER=Microsoft.Jet.OLEDB.4.0;DATA


Source=e:
\
\
webareas
\
\
mk05
\
\
phoneBook.mdb"
);


DBconnection.Open();



// Create and execute SQL query


OleDbCommand

cmdSelectUsers =
new

OleDbCommand


(
"SELECT firstname, surname, phone, location FROM staff
, DBconnection);


OleDbDataReader

dataStaff = cmdSelectUsers.ExecuteReader();



// Instantiate an XML document


XmlDocument

xmlDom =
new

XmlDocument
();


xmlDom.AppendChild(xmlDom.CreateElement(
""
,
"phoneBook"
,
""
));


XmlElement

xmlRoot = xmlDom.DocumentElement;



// Create local references


XmlElement

xmlStaff, xmlFname, xmlSname, xmlTel, xmlLoc;


XmlText

xmlTxt;


string

firstname, surname, telephone, location;

Telephone Directory Web Service

identify the root
element

add the OleDb
sytsem library

Web Services


while

( dataStaff.Read() )


{


// Retrieve the records from the data set


firstname = dataStaff.GetString(0);


surname = dataStaff.GetString(1);


telephone = dataStaff.GetInt32(2).ToString();


location = dataStaff.GetString(3);


// Create XML elements for the records and append them to the DOM


xmlStaff = xmlDom.CreateElement(
"staff"
);


xmlFname = xmlDom.CreateElement(
"fname"
);


xmlText = xmlDom.CreateTextNode(firstname);


xmlFname.AppendChild(xmlText);


xmlStaff.AppendChild(xmlFname);


xmlSname = xmlDom.CreateElement(
"sname"
);


xmlText = xmlDom.CreateTextNode(surname);


xmlSname.AppendChild(xmlText);


xmlStaff.AppendChild(xmlSname);


xmlTel = xmlDom.CreateElement(
"phone"
);


xmlText = xmlDom.CreateTextNode(telephone);


xmlTel.AppendChild(xmlText);


xmlStaff.AppendChild(xmlTel);


xmlLoc = xmlDom.CreateElement(
"loc"
);


xmlText = xmlDom.CreateTextNode(location);


xmlLoc.AppendChild(xmlText);


xmlStaff.AppendChild(xmlLoc);


xmlRoot.AppendChild(xmlStaff);


}


dataStaff.Close();


DBconnection.Close();


return

xmlDom;

}

create and append
elements into the DOM

loop over the data set

return the DOM

Web Services

© 2012

University
of

Greenwich

25

looks remarkably
similar to the SQL
Server web service

Web Services

© 2012

University
of

Greenwich

26

Telephone Directory Web Service


Create a .NET web service that accesses XML
from a URL


That URL could itself be a web service



getDirectory.php reads a staff telephone
directory from a MySQL database


returns a DOM object


is a RESTful web service


uses the PHP5 DOM model


stuweb.cms.gre.ac.uk

Web Services

<?
php

header
(
'Content
-
type: text/xml'
);

require

'/home/mkg01/include/mysql.php'
;

$
link

=
mysql_connect
(
$
host
,
$
user
,
$
passwd
);

mysql_select_db
(
$
dbName
);

$
query

=
'SELECT firstname, surname, phone, location FROM staff ORDER BY surname'
;

$
result

=
mysql_query
(
$
query
,
$
link
);

if

(
mysql_num_rows
(
$
result
) > 0 ) {


$
xmlDom

=
new

DOMDocument();


$
xmlDom
-
>appendChild(
$
xmlDom
-
>createElement(
'directory'
));


$
xmlRoot

=
$
xmlDom
-
>documentElement;


while

(
$
row

=
mysql_fetch_row
(
$
result
) ) {


$
xmlPerson

=
$
xmlDom
-
>createElement(
'staff
'
);


$
xmlFname

=
$
xmlDom
-
>createElement(
'fname'
);


$
xmlText

=
$
xmlDom
-
>createTextNode(
$
row
[0]);


$
xmlFname
-
>appendChild(
$
xmlText
);


$
xmlPerson
-
>appendChild(
$
xmlFname
);


$
xmlSname

=
$
xmlDom
-
>createElement(
'sname'
);


$
xmlText

=
$
xmlDom
-
>createTextNode(
$
row
[1]);


$
xmlSname
-
>appendChild(
$
xmlText
);


$
xmlPerson
-
>appendChild(
$
xmlSname
);


$
xmlTel

=
$
xmlDom
-
>createElement(
'phone'
);


$
xmlText

=
$
xmlDom
-
>createTextNode(
$
row
[2]);


$
xmlTel
-
>appendChild($
xmlText
);


$
xmlPerson
-
>appendChild(
$
xmlTel
);


$
xmlLoc

=
$
xmlDom
-
>createElement(
'loc'
);


$
xmlText

=
$
xmlDom
-
>createTextNode(
$
row
[3]);


$
xmlLoc
-
>appendChild(
$
xmlText
);


$
xmlPerson
-
>appendChild(
$
xmlLoc
);


$
xmlRoot
-
>appendChild(
$
xmlPerson
);


}

}

echo

$
xmlDom
-
>saveXML();

?>

getDirectory.php

loop over the query
results and create a
DOM document


just like the previous
C# example

query MySQL database

output XML mime type

write the DOM
back to the client

Web Services

© 2012

University
of

Greenwich

28

a now familiar sight

Web Services

© 2012

University
of

Greenwich

29

Telephone Directory Web Service

[
WebMethod
]

public

XmlDocument getDirectoryUrlDataSet()

{


// Instantiate a data set and read XML into it from a URL


DataSet

dataSetUrl = new
DataSet
(
"directory"
);


dataSetUrl.ReadXml


(
"http://stuweb.cms.gre.ac.uk/~mkg01/staffWS/getDirectory.php"
);



// Create an XML document and read the data set into it


XmlDocument

xmlDom = new
XmlDocument
();


xmlDom.LoadXml(dataSetUrl.GetXml());


// And return it to the client


return

xmlDom;

}


This is not the best way to read from an external resource
as there is no way to validate the incoming data

Use an XmlTextReader instead

Web Services

© 2012

University
of

Greenwich

30

Telephone Directory Web Service

[
WebMethod
]

public

XmlDocument

getDirectoryUrlTextReader()

{


// Instantiate an XML text reader and read XML into it from a URL


XmlTextReader

myXmlTextReader =
new

XmlTextReader


(
"http://stuweb.cms.gre.ac.uk/~mkg01/staffWS/getDirectory.php"
);



// Create an XML document and load the XML text reader into it


XmlDocument

xmlDom =
new

XmlDocument
();


xmlDom.Load(myXmlTextReader);


// And return it to the client


return

xmlDom;

}

XmlTextReader is a stream XML processor rather like
SAX although SAX is not supported by .NET. This checks
that the XML is well formed and enables the XML to be
validated as it is read.

Web Services

© 2012

University
of

Greenwich

31

Telephone Directory Web Service

[
WebMethod
]

public

XmlDocument

getDirectoryUrlValidating()

{


// Instantiate an XML text reader and read XML into it from a URL


XmlTextReader

xmlTR =
new

XmlTextReader


(
"http://stuweb.cms.gre.ac.uk/~mkg01/staffWS/getDirectory.php"
);


XmlValidatingReader

xmlVR =
new

XmlValidatingReader
(xmlTR);


xmlVR.ValidationType = System.Xml.ValidationType.DTD;



// Assign a validation failure event handler


xmlVR.ValidationEventHandler +=
new

ValidationEventHandler(ValidationHandler);


xmlVR.Read();



// Create an XML document and load the XML text reader into it


XmlDocument

xmlDom =
new

XmlDocument
();


xmlDom.Load(xmlTR);



// And return it to the client


return

xmlDom;

}

method to handle a
validation failure


although it is less than
clear what to do with a
validation failure in a
web service

Web Services

© 2012

University
of

Greenwich

32

XML Aggregation


Web services are used to create interfaces to data
resources


Using DOM structures we can operate on the data


Data from many sources can be aggregated into a single
DOM object


.NET provides alternative programmatic approaches to
XML


DataSet


XmlNavigator


XSLT

Web Services

XML Aggregation

[
WebMethod
]

public

XmlDocument

getDirectories()

{


// Instantiate an XML document and read the SQL database into it


XmlDocument

xmlDom1 =
new

XmlDocument
();


xmlDom1 = getDirectoryDom();






// Instantiate an XML text reader and read XML into it from a URL


XmlTextReader

myXmlTextReader = new
XmlTextReader


(
"http://stuweb.cms.gre.ac.uk/~mkg01/staffWS/getDirectory.php"
);



// Create an XML document and load the XML text reader into it


XmlDocument

xmlDom2 =
new

XmlDocument
();


xmlDom2.Load(myXmlTextReader);



foreach ( XmlElement xmlNode in xmlDom2.DocumentElement.ChildNodes )


{


xmlDom1.DocumentElement.AppendChild(xmlNode);



}



// And return it to the client


return

xmlDom1;

}

reading direct from the
method we created earlier

loop over each node in
the second DOM and
append the node to the
root in the first DOM

Web Services

© 2012

University
of

Greenwich

34

XML Aggregation

Ooops!

Clearly something is not happy here. The nodes do not
belong to the document we are adding them into


we
need to import them or else roll up out sleeves and do it
manually with some DOM programming

Web Services

© 2012

University
of

Greenwich

35

XML Aggregation


This does the trick






Although we could always do it the hard way


which would allow us to adjust the DOM structure as
we migrate nodes

// Loop over each child node in second XML document

foreach

(
XmlNode

xmlNode2
in

xmlDom2.DocumentElement.ChildNodes )

{


// Import each child node into the first XML document


XmlNode

xmlNode1 = xmlDom1.ImportNode(xmlNode2,
true
);


xmlDom1.DocumentElement.AppendChild(xmlNode1);

}

Web Services

© 2012

University
of

Greenwich

36

XML Aggregation

// Create some pointers

XmlElement

xmlStaff, xmlEle;

XmlText

xmlTxt;


// Loop over the staff nodes in the second XML document

foreach

(
XmlNode

xmlStaffNode
in

xmlDom2.DocumentElement.ChildNodes )

{


// Create a new staff element


xmlStaff = xmlDom1.CreateElement(xmlStaffNode.Name);



// Loop over the children of the staff element in the second document


foreach

(
XmlNode

xmlNode
in

xmlStaffNode.ChildNodes )


{


// Create new child elements


xmlEle = xmlDom1.CreateElement(xmlNode.Name);


xmlTxt = xmlDom1.CreateTextNode(xmlNode.InnerText);


xmlEle.AppendChild(xmlext);


xmlStaff.AppendChild(xmlEle);


}



// Append the new staff element to the first XML document


xmlDom1.DocumentElement.AppendChild(xmlStaff);

}

Web Services

hurrah!


either way we manage
to aggregate the
content

Web Services

© 2012

University
of

Greenwich

38

XML Aggregation


Of course we could try a different approach
using data sets instead of XML documents


Data sets provide a useful merge method


although this will complain if data types do not match


e.g. are telephone numbers strings?


converting everything to strings is one work around

Web Services

© 2012

University
of

Greenwich

39

[
WebMethod
]

public

XmlDocument

getDirectories2()

{


// Create an XML text reader to read the ASP.NET Access web service


XmlTextReader

xmlReader1 =
new

XmlTextReader


(
"http://cms
-
stu
-
iis.gre.ac.uk/mk05/..../getDirectoryOledb"
);


DataSet

dataSetReader1 = new
DataSet
();


dataSetReader1.ReadXml(xmlReader1);



// Create an XML text reader to read the PHP web service


XmlTextReader

xmlReader2 =
new

XmlTextReader


(
"http://stuweb.cms.gre.ac.uk/~mkg01/staffWS/getDirectory.php"
);


// Create another data set and load it from the text reader


DataSet

dataSetReader2 =
new

DataSet
();


dataSetReader2.ReadXml(xmlReader2);



// Merge the two data sets


dataSetReader1.Merge(dataSetReader2);



// Instantiate an XML document and load the merged data set into it


XmlDocument

xmlDom =
new

XmlDocument
();


xmlDom.LoadXml(dataSetReader1.GetXml());


// And return it to the client


return

xmlDom;

}

data sets provide a merge
method although it will complain
if the data types don’t match

Web Services

© 2012

University
of

Greenwich

40

<?
php

header
(
'Content
-
type: text/xml'
);

require

'/home/mkg01/include/mysql.php'
;

$
link

=
mysql_connect
(
$
host
,
$
user
,
$
passwd
);

mysql_select_db
(
$
dbName
);

$
query

=
'SELECT firstname, surname, phone, location FROM staff ORDER BY surname'
;

$
result

=
mysql_query
(
$
query
,
$
link
);

if

(
mysql_num_rows
(
$
result
) > 0 ) {


$
xmlDom

=
new

DOMDocument();


$
xmlDom
-
>appendChild(
$
xmlDom
-
>createElement(
'directory'
));


$
xmlRoot

=
$
xmlDom
-
>documentElement;


while

(
$
row

=
mysql_fetch_row
(
$
result
) ) {


$
xmlPerson

=
$
xmlDom
-
>createElement(
'staff
'
);


$
xmlFname

=
$
xmlDom
-
>createElement(
'fname'
);


$
xmlText

=
$
xmlDom
-
>createTextNode(
$
row
[0]);


$
xmlFname
-
>appendChild(
$
xmlText
);


$
xmlPerson
-
>appendChild(
$
xmlFname
);


$
xmlSname

=
$
xmlDom
-
>createElement(
'sname'
);


$
xmlText

=
$
xmlDom
-
>createTextNode(
$
row
[1]);


$
xmlSname
-
>appendChild(
$
xmlText
);


$
xmlPerson
-
>appendChild(
$
xmlSname
);


$
xmlTel

=
$
xmlDom
-
>createElement(
'phone'
);


$
xmlText

=
$
xmlDom
-
>createTextNode(
$
row
[2]);


$
xmlTel
-
>appendChild($
xmlText
);


$
xmlPerson
-
>appendChild(
$
xmlTel
);


$
xmlLoc

=
$
xmlDom
-
>createElement(
'loc'
);


$
xmlText

=
$
xmlDom
-
>createTextNode(
$
row
[3]);


$
xmlLoc
-
>appendChild(
$
xmlText
);


$
xmlPerson
-
>appendChild(
$
xmlLoc
);


$
xmlRoot
-
>appendChild(
$
xmlPerson
);


}

}

we've seen all
this before

soapAggregator.php

do the same
thing with PHP

Web Services

© 2012

University
of

Greenwich

41

$
client

=
new

SoapClient(
"http://cms
-
stu
-
iis.gre.ac.uk.../phoneBook.asmx?WSDL"
);

$
xmlString

=
$
client
-
>getDirectoryDom()
-
>getDirectoryDomResult
-
>any;

$
xmlDom2

=
new

DOMDocument();

$
xmlDom2
-
>loadXML($xmlString);


foreach

(
$
xmlDom2
-
>documentElement
-
>childNodes as $staffNode ) {


$
xmlPerson

=
$
xmlDom1
-
>createElement($staffNode
-
>nodeName);


foreach

(
$
staffNode
-
>childNodes as
$
xmlNode

) {


$
xmlElement

=
$
xmlDom1
-
>createElement(
$
xmlNode
-
>nodeName);


$
xmlText

=
$
xmlDom1
-
>createTextNode(
$
xmlNode
-
>nodeValue);


$
xmlElement
-
>appendChild(
$
xmlText
);


$
xmlPerson
-
>appendChild(
$
xmlElement
);


}


$
xmlRoot
-
>appendChild(
$
xmlPerson
);

}


echo

$
xmlDom1
-
>saveXML();

?>

soapAggregator.php

create a SOAP client using
the ASP.NET WSDL

merge the two
DOM objects

Web Services

© 2012

University
of

Greenwich

42

Web Services

© 2012

University
of

Greenwich

43

Adding A Processing Instruction

[
WebMethod
]

public

XmlDocument

showDirectory()

{


// Instantiate an XML document and read the SQL database into it


XmlDocument xmlDom =
new

XmlDocument
();


xmlDom = getDirectoryDom();



// Create a PI and append it to the document





XmlProcessingInstruction

PI = xmlDom.CreateProcessingInstruction


(
"xml
-
stylesheet", "href='directory.xsl' type='text/xsl'"
);


xmlDom.InsertBefore(PI, xmlDom.DocumentElement);



// Return the document to the client


return

xmlDom;

}

Web Services

© 2012

University
of

Greenwich

44

oh no!


because this is a Web Method
the processing instructions has
been stripped out

Web Services

© 2012

University
of

Greenwich

45

Adding Processing Instruction


It is not entirely surprising that the processing instruction
is filtered out from a web service


Add a Generic Handler to the project


.ashx


Add code to aggregate XML and add a processing
instruction into the page load event


Return all of the XML using the Response object


Don’t forget to also use the Response object to send out
the correct mime type


text/xml


Web Services

© 2012

University
of

Greenwich

46

using
System.IO;


private

void

Page_Load(
object

sender,
EventArgs

e)

{


// Instantiate an XML text reader and read XML into it from a URL


XmlTextReader
xmlTextReader1 =
new

XmlTextReader


(
"http://cms
-
stu
-
iis.gre.ac.uk/mk05/.../getDirectoryDom"
);



// Create an XML document and load the XML text reader into it


XmlDocument

xmlDom1 =
new

XmlDocument
();


xmlDom1.Load(xmlTextReader1);






// Instantiate an XML text reader and read XML into it from a URL


XmlTextReader

xmlTextReader2 =
new

XmlTextReader


(
"http://stuweb.cms.gre.ac.uk/~mkg01/staffWS/getDirectory.php"
);



// Create an XML document and load the XML text reader into it


XmlDocument

xmlDom2 =
new

XmlDocument
();


xmlDom2.Load(xmlTextReader2);



Adding Processing Instruction

at this stage we have two XML
documents obtained from two
web services

Web Services

© 2012

University
of

Greenwich

47


// Loop over each child node in second XML document


foreach

(
XmlNode

xmlNode2
in

xmlDom2.DocumentElement.ChildNodes )


{


// Import each child node into the first XML document


XmlNode

xmlNode1 = xmlDom1.ImportNode(xmlNode2, true);


xmlDom1.DocumentElement.AppendChild(xmlNode1);


}



// Create and insert processing instruction




XmlProcessingInstruction

PI = xmlDom1.CreateProcessingInstruction


(
"xml
-
stylesheet"
,
"href=
\
"directory.xsl
\
" type=
\
"text/xsl
\
""
);


xmlDom1.InsertBefore(PI, xmlDom1.DocumentElement);



// Write it all back to the client


StringWriter

sw =
new

StringWriter
();


XmlTextWriter

xtw =
new

XmlTextWriter
(sw);


xmlDom1.WriteTo(xtw);


context.Response.ContentType =
"text/xml"
;


context.Response.Write(sw);

}

Adding Processing Instruction

output mime type

output XML

Web Services

© 2012

University
of

Greenwich

48

Adding Processing Instruction

oh hurrah!


here the XML returning to
the client contains the PI
linking to a simple XSLT
stylesheet

Web Services

© 2012

University
of

Greenwich

49

Adding Processing Instruction


Try the same trick in PHP…


Add one extra line to getDirectory.php





The nice thing about DOM is the way the code works
pretty much the same in both PHP and C#


Add the same DOM code into PHP and aggregate some
XML

$
xmlDom
-
>appendChild(
$
xmlDom
-
>createProcessingInstruction


(
'xml
-
stylesheet'
,
'href="directory.xsl" type="text/xsl"'
));

Web Services

© 2012

University
of

Greenwich

50

Adding Processing Instruction

XML merged and XSLT
processed using PHP with
the same DOM code as
used in C#

Web Services

© 2012

University
of

Greenwich

51

Server Side XSLT Processing


Not all browsers support XSLT processing


Perhaps the XSLT processing is better handled at the
server


add another Generic Handler

// Create a StringWriter to write back the HTML

StringWriter

sw =
new

StringWriter
();


// Create an XSLT transformer and load in the XSLT file

XmlTextReader
xsltSource

=
new

XmlTextReader
(
"directory.xsl"
);

XslCompiledTransform

xslt =
new

XslCompiledTransform
();

xslt.Load(xsltSource);


// Transform the XML (with a null XmlResolver)

xslt.Transform(xmlDom1,
null
, sw);


// Return the results to the client

context.Response.ContentType =
"text/html"
;

context.Response.Write(
"<?xml version=
\
"1.0
\
" encoding=
\
"UTF
-
8
\
"?>
\
n"
);

context.Response.Write(sw);

Web Services

© 2012

University
of

Greenwich

52

Server Side XSLT Processing

just when you thought that
you had control over
ASP.NET a pesky meta tag
appears

Web Services

© 2012

University
of

Greenwich

53

SQL Insert Web Service


So far we have been retrieving information
from various databases


often we want to
insert or modify.


Visual Studio makes it easy to create a
suitable web service

Web Services

© 2012

University
of

Greenwich

54

[
WebMethod
]

public

string

insertRecord(
string

txtFname,
string

txtSname,
string

txtTel,
string

txtLoc)

{


if

( txtFname ==
""
|| txtSname ==
""

|| txtTel ==
""

|| txtLoc ==
""

)


{


return

"Incomplete data"
;


}


else



{


int

number =
int
.Parse(txtTel);



// Open a connection the the SQL Server


SqlConnection

sqlConn =
new

SqlConnection
();


sqlConn.ConnectionString =
"<SQL Server connection string>"
;


sqlConn.Open();



// Create a SQL query


SqlCommand

insertCmd = sqlConn.CreateCommand();


insertCmd.CommandType = CommandType.Text;


insertCmd.CommandText =
"INSERT INTO phoneBook (fname, sname, phone, loc)


VALUES ('" + txtFname+ "', '" + txtSname+ "', " + number + ", '" + txtLoc + "')"
;



insertCmd.ExecuteNonQuery();


return

"Record inserted"
;


}

}

SQL Insert Web Service

report validation fail

report success

validate input

Web Services

© 2012

University
of

Greenwich

55

SQL Insert Web Service

Web Services

© 2012

University
of

Greenwich

56

Conclusions


It's all so easy


especially when it's RESTful


Visual Studio does most of the work


wish we had VS for PHP


PHPeclipse, Netbeans


These examples show main points


coding would benefit from try catch constructs

Web Services

© 2012

University
of

Greenwich

57

Questions?