Simple Silverlight 2 app - APIDemo - Part 2, Building the FeaturePics API Demo

This post is a continuation of Simple-Silverlight-2-app-APIDemo-Part-1-Building-the-DiggSample. You might want to start with that, as this part modifies it as necessary to extract data using the  FeaturePics.com Developer's Search API. You can see a sample of the xml returned with Sample Query. So the task is to map the fields returned by the FeaturePics query into the display formerly used for the DiggSample.

First step was to copy all the files to a new directory and rename the project, including the namespace, to APIDemo. This could have been done without changing the namespace or copying the files, but I wanted to retain a working copy of the DiggSample while creating ApiDemo.

The Image Class

The DiggSample has the public class DiggStory where the data for each Digg Story is stored. I created a similar class:

namespace APIDemo
{
    public class FPImage
    {
        public int ImageId { get; set; }
        public string ImageName { get; set; }
        public string Caption { get; set; }
        public Uri ImagePage { get; set; }
        public string ImageFile { get; set; }
        public int Width { get; set; }
        public int Height { get; set; }
        public string Author { get; set; }
        public Uri AuthorPage { get; set; }
    }
}

The API Query

Now that I have a place to store individual image records, it was time to obtain the data to display. If you followed the DigSample tutorial, you know that the api query is in Page.xaml.cs and looks like this:
        string diggUrl = String.Format('http://services.digg.com/stories/topic/{0}?count=20&appkey=http%3A%2F%2Fscottgu.com', topic);

The FeaturePics API accepts one or more keywords, so I replace spaces, if any, with %20. The FeaturePics query version looks like this:

        string fpUrl = String.Format('http://adminservices.featurepics.com/GetImagesExt.asmx/SearchResultsExt?Keywords={0}&NumberPerPage=30', topic.Replace(' ', '%20'));

This query should return a set of 30 images related to the contents of 'topic'. I should probably note there are other similar query possibilities returning data sets with somewhat different characteristics, but this is a good example.

Testing the Query

I assigned the FPImage fields to the expected query fields, compiled, and entered the first search term, cat. Nothing. Nothing at all was processed by my code. In the course of debugging the problem I noted these declarations:

  <?xml version='1.0' encoding='utf-8' ?>
- <ImageSet xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns='http://AdminServices.FeaturePics.com/'>

This is a standard .NET Web Service xml output format, but it was the first time I have coded the consumption of such a web service, and I wasted some time learning the necessary syntax. All of the field tags contain the "http://AdminServices.FeaturePics.com/" string as well as the field name. One way to specify the tag name is:

ImageId = (int)image.Element("{http://AdminServices.FeaturePics.com/}ImageId"),

Or, you can define the namespace once:

    // define the namespace declaration
    XNamespace nsFP = "http://AdminServices.FeaturePics.com/";

and subsequently use that definition:

                ImageId = (int)image.Element(nsFP + "ImageId"),


This is how I ended up populating the FPImage class:

void DisplayImages(string xmlContent)
{
    XDocument xmlImages = XDocument.Parse(xmlContent);
    // define the namespace declaration
    XNamespace nsFP = "http://AdminServices.FeaturePics.com/";
    var images = from image in xmlImages.Descendants(nsFP + "ImageExt")
             where image.Element(nsFP + "ImageFile").Value != null
             select new FPImage
              {
                ImageId = (int)image.Element(nsFP + "ImageId"),
                ImageName = ((string)image.Element(nsFP + "ImageName")).Trim(),
                ImageFile = (string)image.Element(nsFP + "ImageFile"),
                ImagePage = new Uri((string)image.Element(nsFP + "ImagePage")),
                Caption = !String.IsNullOrEmpty((string)image.Element(nsFP + "Caption")) ? (string)image.Element(nsFP + "Caption") : "No caption found",
                Author = !String.IsNullOrEmpty((string)image.Element(nsFP + "Author")) ? (string)image.Element(nsFP + "Author") : "Artist attribution not found",
                AuthorPage = new Uri((string)image.Element(nsFP + "AuthorPage")),
                Width = (int)image.Element(nsFP + "Width"),
                Height = (int)image.Element(nsFP + "Height")
              };
    ImagesList.SelectedIndex = -1;
    ImagesList.ItemsSource = images;
}

Some of the early FeaturePics images do not have the Caption or Author fields filled in, so I provide a replacement string.

Displaying the results

The main result page is Page.xaml. Not many changes were made here, text labels were changed to refer to FeaturePics rather than to Digg, and field names were changed to map those found in FPImage.

The image details are displayed in StoryDetailsView.xaml, and it too is very similar to the version in DiggSample. I added a row for the Artist's Images link, and changed the dimensions both of the page itself, and of the column widths. These changes were made in StoryDetailsView.xaml. And of course the field names were changed to match those in FPImage. There were also some CSS type changes made in App.xaml.

Using the control

The DiggSample uses an extremely simple html page to display the control. I wanted something that would show off the possibilities a bit better, so I set about creating APIDemo.html.

The biggest change here was setting height and width constraints on the #silverlightControlHost CSS definition. The page width was also limited and text added above and to the right of the control.

After these changes the control would not display in FireFox. After some trial and error, I found that deleting the CSS body "overflow: auto; " improved the IE display and fixed the FireFox problem.

The point of these changes is, of course, to demonstrate that the APIDemo control could be a part of any web page. It is one possible way to use the FeaturePics search API. And best of all, I learned a bit about Silverlight in the process.

Project files

You can download a copy of my project: ApiDemo.zip.

28. August 2008 11:32 by Kal | Comments (0) | Permalink

Simple Silverlight 2 app - APIDemo - Part 1, Building the DiggSample

Scott Guthrie published an eight step Silverlight 2 Beta 1 tutorial. The page that links to all eight parts and explains how to get started is Get Started Building Silverlight 2 Applications.

I did not even really understand what Silverlight is, so decided to get my feet wet with this very basic tutorial. I followed the first two or three tutorials religiously, typing in the code and experiencing a bit of how it works. Then I read the remainder pretty carefully and downloaded the complete demo application at the end.

Scott's demo application performs a search of the Digg api and displays selected parts of the xml returned.

Digg.com has a pretty cool set of Digg APIs that they publish over HTTP.  Because they have a Flash cross-domain policy file in place on their server, we can call them directly from our Silverlight Digg client application (and not require us to tunnel back through our web-server to reach their APIs).

FeaturePics.com has recently published a Developers API, and I have not yet seen the code used in an application, so I hit on the idea of modifying Scott's demo app to provide a FeaturePics API demo. So that was what I set out to do.

Version Issues

When I tried to compile the downloaded Digg demo app there were a few changes necessary due to the Silverlight on my computer is Beta 2 and the code is for Beta 1. Probably the most difficult of these to resolve was the WatermarkedTextBox control could not be found. Google found Kathy Kam, Reflection on the CLF and .NET.

One breaking change you may have noticed between Silverlight 2 Beta 1 and Beta 2 is that WatermarkedTextBox is no longer available in the Silverlight SDK (System.Windows.Controls.Extended.dll). 

We decided to remove the control because in a future version of Silverlight, we will be adding a “Watermark” property to TextBox. Given this upcoming change, it does not make sense to have "WatermarkedTextBox" as a separate control, so we decided to remove the control from Silverlight 2.

Because the update to TextBox will not happen until a future version of Silverlight feel free download and use the WatermarkedTextBox source code and unit test in the mean time. By downloading the source and unit tests you accept the license.

Here is an example on how to use it:

image

So I downloaded the referenced project, built it, and referenced it in DiggSample, which produced an immediate error because I had previously referenced the System.Windows.Controls.Extended that is included in Beta 2. Possibly I could have just removed that previous reference, but instead I renamed the download project to Extended2. Then I added the following line to the controls definition, and the app compiled.

xmlns:wtb='clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Extended2'

I happen to have available a couple of vacant domains and I used one of them DiggSample, Beta 2 Version. The search is for Digg Topics only, so try something like football or soccer. 

16. August 2008 12:53 by Kal | Comments (0) | Permalink

Calendar

<<  April 2014  >>
MoTuWeThFrSaSu
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

View posts in large calendar

Month List