June 2006 Entries
That’s right folks, I’m off to sunny Spain for two weeks R&R; I’ll be back around July 17. In the meantime, you kids have fun, and try not to wreck the place whilst I’m gone.
Episode #4 in the series the Journey to the 2007 Open has been posted here.
Tags: Carnoustie, Golf, 2007 Open, Vlog, Podcast
I've just been across to Dave Winer's site. Today, he's complaining about the lack of support for XML-RPC in the Newsgator roadmap. He says
...which I know from lots of experience means I have to work real hard just to try their stuff out. Too hard.
Really Dave? What tools are you using then? Here I made a post showing code that accesses the youtube API via REST and here I made a post showing code that accessed an RSS feed. As you can see the code doesn't change that much. The reason for this is that under it all the "stuff" you are dealing with is just XML. Well you know what? If I had to use an API that used XML-RPC than the code still wouldn't change that much as it's still XML under the hood.
All of which makes me wonder if using REST over XML-RPC is honestly a real hardship for Dave, or is it just that they don't support his baby (XML-RPC).
Tags: Dave Winer, XML-RPC, REST, Newsgator, Platform Wars
Get it while it's hot
Microsoft .NET Compact Framework version 2.0 SP1 release has been completed and is in the process of being released. This service pack was driven customer feedback including improvements in stability, adds new debugging features, extended platform support, and new developer functionality.
.NET Compact Framework Team.
Tag: .Net Compact Framework 2.0 SP1
I’ve put up a new golf vlog. This one is an interview with Simon Golding, a Sky Sports TV director, who was at Carnoustie filming a Sir Steve Redgrave charity golf match.
Tags: Golf, Carnoustie Open 2007
Erm, well, live! Get it here.
Tag: Windows Live Messenger.
Well maybe not. Can you believe that since I mentioned that I’d be writing a Smalltalk cookbook, as a set of blog postings, the page that I referenced has been deleted. Grrrr! Ah well, I might base it on the Python Cookbook instead as I have a paper copy of that.
Tag: Smalltalk Cookbook
I noticed the YouTube site has an API so I've been playing around with it. Here's an example of how to call a YouTube API from C# to list the videos relating to golf.
protected void Page_Load(object sender, EventArgs e)
{
//GS - Empty the buffer of anything written already
Response.Clear();
//GS - Call the YouTube api to list all videos for a tag
string uri = "http://www.youtube.com/api2_rest?";
uri += "method=youtube.videos.list_by_tag";
uri += "&dev_id=YOUR_KEY_HERE";
uri += "&tag=golf";
XPathDocument xpd = null;
try
{
xpd = new XPathDocument(uri);
}
catch (XmlException xe)
{
Response.Write("The following xml error occurred: " +
xe.Message);
Response.End();
return;
}
//GS - Create a navigator
XPathNavigator xpn = xpd.CreateNavigator();
//GS - Handle any errors
XPathNodeIterator xniError = xpn.Select(@"/ut_response");
xniError.MoveNext();
if(xniError.Current.GetAttribute("status",String.Empty)=="fail")
{
//GS - Get the error
string expression = "/ut_response/error/description";
string errorText = xpn.SelectSingleNode(expression).InnerXml;
//GS - Inform the user
Response.Write("The YouTube API reported the " +
"following error: " + errorText);
Response.End();
return;
}
//GS - No errors so get all the video elements returned
try
{
XPathNodeIterator xni =
xpn.Select(@"/ut_response/video_list/video");
//GS - Write out a heading
Response.Write("<h1>Golfing Videos</h1>");
//GS - Start an unordered list
Response.Write("<ul>");
//GS - For each video write thumb nail image and title
string title = "";
string url = "";
string thumbUrl = "";
while (xni.MoveNext())
{
title = xni.Current.SelectSingleNode(@"title").InnerXml;
url = xni.Current.SelectSingleNode(@"url").InnerXml;
thumbUrl =
xni.Current.SelectSingleNode(@"thumbnail_url").InnerXml;
Response.Write("<li>");
Response.Write("<img height='75' width='75' src='" +
thumbUrl + "' />");
Response.Write("<br />");
Response.Write("<a href='" + url + "'>" + title + "</a>");
Response.Write("<p />");
Response.Write("</li>");
}
//GS - Close the unordered list
Response.Write("</ul>");
//GS - Write to the browser
Response.End();
}
catch (XPathException xpe)
{
Response.Write("The following XPath exception occurred: "
+ xpe.Message);
Response.End();
return;
}
}
Tags: YouTube, Mashup, C#
For those of you following the run up to the 2007 Open, I’ve put up a new video posting here.
Tags: Golf, Carnoustie, Open 2007
…and, as usual, the guys at the National Oceanic & Atmospheric Administration have their eye on what’s going on. They provide several feeds detailing the hurricane situation. You can find them here.
I’ve written a little web page that makes use of the feed, just to show you how to consume it. The code’s below and is fairly self explanatory.
protected void Page_Load(object sender, EventArgs e)
{
//GS - Remove any content already written to the buffer
Response.Clear();
//GS - Write the html header
Response.ContentType = "text/html";
//GS - Open the RSS feed
XPathDocument xpd = null;
try
{
xpd =
new XPathDocument(@"http://www.nhc.noaa.gov/index-at.xml");
}
catch (XmlException xe)
{
Response.Write("The following xml error occurred: " + xe.Message);
Response.End();
}
//GS - Create a navigator
XPathNavigator xpn = xpd.CreateNavigator();
//GS - Get the URL to the logo of NOAA
try
{
XPathNavigator Node =
xpn.SelectSingleNode(@"/rss/channel/image/url");
//GS - Write the image
Response.Write("<img src='" + Node.InnerXml + "' /><p />");
//GS - Get the title
Node = xpn.SelectSingleNode(@"/rss/channel/title");
//GS - Write the out the title
Response.Write("<h1>" + Node.InnerXml + "</h1>");
//GS - Get the subtitle
Node = xpn.SelectSingleNode(@"/rss/channel/description");
//GS - Write out the subtitle
Response.Write("<h2>" + Node.InnerXml + "</h2>");
//GS - Get all the items
XPathNodeIterator xpni = xpn.Select(@"/rss/channel/item");
//GS - Start an unordered list
Response.Write("<ul>");
//GS - Add each item to the list
string title = "";
string url = "";
while (xpni.MoveNext())
{
if (xpni.Current.MoveToFirstChild())
{
title = xpni.Current.InnerXml;
if (xpni.Current.MoveToNext())
{
url = xpni.Current.InnerXml;
}
}
Response.Write("<li><a href='" + url + "'>" +
title + "</a></li>");
}
//GS - Close the unordered list
Response.Write("</ul>");
//GS - We're done. Flush and close the buffer.
Response.End();
}
catch (XPathException xpe)
{
Response.Write("The following XPathException occurred: " +
xpe.Message);
Response.End();
}
}
Tags: Hurricanes, RSS, C#
we have decided to rename WinFX to the .NET Framework 3.0. .NET Framework 3.0 aptly identifies the technology for exactly what it is – the next version of our developer framework.
Somasegar's WebLog : .NET Framework 3.0.
Tags: WinFX, .Net Framwork 3.0
Is this a wind up?
First, I love Microsoft and Microsoft did not lose me — at least as a supporter and friend. I am not throwing away my Tablet PC or my Xbox or my other Microsoft stuff. :-)
Scobleizer - Microsoft Geek Blogger » Correcting the Record about Microsoft.
Goes off to check it’s not April 1.
If you are and you want your product to work on Microsoft’s shiny new Vista release then you need to visit this site and pay attention to what it says. Can’t wait to see how netBake stands up.
Tag: Vista Readiness
If so, then this site will bring back a few memories.
Tag: 80’s Music
A RESTful API is a lightweight web service and here’s an example of how to implement one in ASP.NET 2.0. Firstly, we need a web page to do some work for us, in this example, the web page will tell us if a supplied customer number is valid or not.
public partial class ValidateCustomerNumber : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
//GS - Get the account number
string accountNumber = Request.QueryString.Get("AccountNo");
//GS - An empty account number is not valid
if (accountNumber == String.Empty)
{
ReturnAccountNumberNotValid();
return;
}
//GS - Contact the database system to verify account number
OdbcCommand cmd = new OdbcCommand();
OdbcConnection conn = new OdbcConnection(WebConfigurationManager.
ConnectionStrings["myConnectionName"].ConnectionString);
cmd.Connection = conn;
cmd.CommandType = CommandType.Text;
cmd.CommandText = "SELECT AccountNo FROM Customers WHERE " +
"RTrim(AccountNo) = '" + accountNumber + "'";
object accountNumberFromDB = "";
try
{
cmd.Connection.Open();
accountNumberFromDB = cmd.ExecuteScalar();
//GS - ExecuteScaler() will return null if there is no hits on the
//database
if (null == accountNumberFromDB)
{
accountNumberFromDB = "";
}
else
{
accountNumberFromDB = accountNumberFromDB.ToString();
}
}
finally
{
//GS - Tidy up
if (cmd.Connection.State == ConnectionState.Open)
{
cmd.Connection.Close();
}
cmd.Connection.Dispose();
cmd.Dispose();
}
//GS - Send back the return based on result of query
if (string.Empty == (string)accountNumberFromDB)
{
ReturnAccountNumberNotValid();
}
else
{
ReturnAccountNumberIsValid();
}
}
/// <summary>
/// Answers that the account number is not valid
/// </summary>
private void ReturnAccountNumberNotValid()
{
SendToClient(FormatStringAsXML("0"));
}
/// <summary>
/// Answers that the account number is valid
/// </summary>
private void ReturnAccountNumberIsValid()
{
SendToClient(FormatStringAsXML("1"));
}
/// <summary>
/// Sends the string to the client
/// </summary>
/// <param name="s">string</param>
private void SendToClient(string s)
{
//GS - Clear the html in the response object
Response.Clear();
//GS - Add the header
Response.ContentType = "text/html";
//GS - Send the string to the client
Response.Write(s);
Response.End();
}
/// <summary>
/// Wraps the msg up in xml for return
/// </summary>
/// <param name="msg">string</param>
/// <returns>string</returns>
private string FormatStringAsXML(string msg)
{
//GS - Create a response string
StringBuilder sb = new StringBuilder();
//GS - Add the xml
sb.AppendLine("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
sb.AppendLine("<results>");
sb.AppendLine("<isValid>");
sb.AppendLine(msg);
sb.AppendLine("</isValid>");
sb.AppendLine("</results>");
//GS - Return the string
return sb.ToString();
}
}
Now that we have done that, we need somewhere for our API to live, something like http://www.MyDomain.com/customer/validate/ will do nicely. Now, we need something to consume our web service, like so
/// <summary>
/// Answers whether or not the supplied customer number is valid
/// </summary>
/// <returns>Bool</returns>
private bool CustomerNumberValid()
{
string accountNo = _txtCustomerNumber.Text.Trim();
//GS - Account number is not mandatory so empty is valid
if (accountNo == String.Empty)
{
return true;
}
//GS - build a uri string for the api call
string uri =
WebConfigurationManager.AppSettings["ValidateAccountCodeUri"];
uri += "?AccountNo=";
uri += accountNo;
//GS - Call the api
XPathDocument xpd = new XPathDocument(uri);
//GS - Create the navigator
XPathNavigator xpn = xpd.CreateNavigator();
//GS - Return whether or not the account number was valid
XPathNavigator node = xpn.SelectSingleNode(@"/results/isValid");
return (node.InnerXml == String.Empty) ? false :
Convert.ToBoolean(Convert.ToInt16(node.InnerXml));
}
And that's all there is to it.
Tags: RESTful, ASP.NET
The exclusion of computer programs from the patenting process will be tested in a Court of Appeal case that could turn UK patent law on its head. Lord Justice Jacob has given permission for an appeal to be heard over an online system of document assembly that was previously ruled to be excluded from the patent provision. Jacob's decision could clear up a till-now murky area of patent law.
English Judge OKs software patent case | The Register.
For those of you who are following our efforts to blog the run up to the 2007 Open Championship (in partnership with the venue course) you might like to check out this amazing golf shot.
My wife had her guides at Crombie Park on Saturday, helping the rangers there as part of their community service badge. Whilst there someone took this picture of my wife and the other two leaders. There was something about it that made me think of Macbeth :)
|