Purpose of document
- This document provides sample .NET code to create, get, update, and delete a UW Groups web service resource
- It does not provide an example of how to modify the membership, though this should be fairly straightforward once you have the .NET code and read the Groups Service API v2.
Alternatives
- The forthcoming ASP.NET 3.5 Extensions offers a .NET web client for consuming RESTful web resources. This library makes querying and updating web resources behave like other LINQ operations, and may be of interest.
Requirements
- .NET 2.0/3.0/3.5
- UWCA certificate, that has been authorized to the UW Groups Web Service
- UW Groups web service v1
Refer to Groups Service API v2 to understand the resources.
The steps below outline what you need to do to get and parse the XHTML from a group resource.
To see how to create, update, and delete, please download the following Visual Studio .NET 2008 C# solution. That solution also contains a simple RESTful client which is used in the test code.
Include namespaces
using System.Security.Cryptography.X509Certificates;
using System.Web;
using System.Net;
using System.Xml;
using System.IO;
Construct the URI
string uri = "https://iam-ws.u.washington.edu:7443/group_sws/v2/group/u_nebula_gca";
Create a GET request
HttpWebRequest _request = (HttpWebRequest)HttpWebRequest.Create(uri);
_request.AllowAutoRedirect = true;
_request.Method = "GET";
Find the certificate in the certificate store
string subject = "[MyCertificateSubjectName]";
X509Certificate cert = null;
X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly);
X509Certificate2Collection col =
store.Certificates.Find(X509FindType.FindBySubjectName,
subject, true);
try {
cert = col[0];
}
catch (Exception ex) {
throw new Exception(String.Format("Certificate '{0}' not found", subject), ex);
}
Attach the certificate
_request.ClientCertificates.Add(_cert);
Get the response, and cast it to a HttpWebResponse
If the HttpWebRequest encounters an error accessing the resource (HttpStatusCode > 200), it throws a WebException
To be able to determine what kind of error happened, it is neccessary to handle that exception, retrieve
the WebResponse object, cast it to an HttpWebResponse, and inspect the HttpStatusCode
WebResponse webResponse = null;
HttpWebResponse _response = null;
try {
webResponse = request.GetResponse();
_response = (HttpWebResponse)webResponse;
}
catch (WebException ex) {
webResponse = ex.Response;
_response = (HttpWebResponse)webResponse;
}
Handle any exceptional status codes
if (_response.HttpStatusCode > 200) {
// if the server was busy, wait and try again
// was there a redirect?
...
}
Load the response stream into an XmlDocument object
XmlDocument xmlDoc = null;
using (Stream responseStream = _response.GetResponseStream()) {
xmlDoc = new XmlDocument();
xmlDoc.Load(responseStream);
}
Retrieve values from the XmlDocument using xPath query
// in order to do xPath, we need to add any namespaces from the xhtml document with prefixes
XmlNamespaceManager nsmgr = new XmlNamespaceManager(xmlDoc.NameTable);
nsmgr.AddNamespace(String.Empty, "http://www.w3.org/1999/xhtml");
nsmgr.AddNamespace("t", "http://www.w3.org/1999/xhtml");
// Regid
XmlElement regidEl = (XmlElement)xmlDoc.SelectSingleNode("//t:*[@class='regid']", nsmgr);
this.Regid = regidEl.InnerText;
// Description
XmlElement descEl = (XmlElement)xmlDoc.SelectSingleNode("//t:*[@class='description']", nsmgr);
if (descEl != null) {
this.Description = descEl.InnerText;
}
// Names
this.Names = null;
XmlNodeList nameList = (XmlNodeList)xmlDoc.SelectNodes("//t:*[@class='name']", nsmgr);
foreach (XmlElement nameEl in nameList) {
this.Names.Add(nameEl.InnerText);
}
Resources