• Silverlight Flickr Badge

    Taking another cue from some great stuff Joel is doing, I liked his implementation of the ‘Leopard Screen Saver’ but wanted to make it more ‘real’ for me.  So I wired it up to my Flickr account.  Result here (using Silverlight Streaming):

    I only had to change a few things.

    First, in the Page_Loaded event, I removed the timer start function.  This was because with interacting with Flickr it was going to be async.  I didn’t want the timer to start until I knew the image collection was built.

    My BuildCollection function now looks like this:

    private void BuildCollection()
    {
        // get Flickr NSID
        WebClient fu = new WebClient();
        fu.DownloadStringCompleted += new DownloadStringCompletedEventHandler(fu_DownloadStringCompleted);
        fu.DownloadStringAsync(new Uri(string.Format(FLICKR_USER_SEARCH, App.FlickrUser)));
    }

    This is a first call to get the NSID (internal Flickr user_id parameter) based on an initParam the user sends in.  The FLICKR_USER_SEARCH is just a const string parameter to the Flickr API rest call (with my API key in it) which looks like this:

    const string FLICKR_USER_SEARCH = "http://api.flickr.com/services/rest/?method=flickr.urls.lookupuser
        &api_key=[yours]
        &url=http://flickr.com/photos/{0}";

    I also use a FLICKR_USER_PHOTOS const which is like this:

    const string FLICKR_USER_PHOTOS = "http://api.flickr.com/services/rest/?method=flickr.photos.search
        &user_id={0}
        &api_key=[yours]";

    The completed event handler for the user search call looks like:

    void fu_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
    {
        XDocument resp = XDocument.Parse(e.Result);
    
        string nsid = resp.Element("rsp").Element("user").Attribute("id").Value;
    
        WebClient p = new WebClient();
        p.DownloadStringCompleted += new DownloadStringCompletedEventHandler(p_DownloadStringCompleted);
        p.DownloadStringAsync(new Uri(string.Format(FLICKR_USER_PHOTOS, nsid)));
    }

    to retrieve the NSID.  With that I then start the search photos call to retrieve 42 photos.  The sample is a little hard-coded with count values, but this is just a quick change to see if it would work.  When the async operation to search the photos returns, I use some LINQ to mash them into FlickrImage object types using a custom class I put in my Silverlight application.

    public class FlickrImage
    {
        public string id { get; set; }
        public string farm { get; set; }
        public string server { get; set; }
        public string secret { get; set; }
        public string title { get; set; }
        public int tagid { get; set; }
        public string url
        {
            get
            {
                return string.Format("http://farm{0}.static.flickr.com/{1}/{2}_{3}_m.jpg",
                   farm, server, id, secret);
            }
        }
    }

    and then the LINQ query:

    XDocument xml = XDocument.Parse(e.Result);
    
    var photos = from results in xml.Descendants("photo")
                 select new FlickrImage
                 {
                     id = results.Attribute("id").Value.ToString(),
                     farm = results.Attribute("farm").Value.ToString(),
                     server = results.Attribute("server").Value.ToString(),
                     secret = results.Attribute("secret").Value.ToString(),
                     title = results.Attribute("title").Value.ToString()
                 };

    Once I have these, I essentially moved the iteration code Joel had into a foreach loop for my images and then started the timer.

    foreach (FlickrImage photo in photos)
    {
        Uri imageUri = new Uri(photo.url, UriKind.Absolute);
    
        if (i <= 16)
        {
            Tile tile = new Tile();
            Media media = new Media(imageUri, true);
            tile.Media = media;
    
            if (col % 4 == 0)
            {
                row++;
                col = 0;
            }
            tile.SetValue(Grid.ColumnProperty, col.ToString());
            tile.SetValue(Grid.RowProperty, row.ToString());
            this.LayoutRoot.Children.Add(tile);
    
            col++;
            _tiles.Add(tile);
            _images.Add(media);
    
        }
        else
            _images.Add(new Media(imageUri, false));
    
        i++;
    }
    
    _timer.Start();

    The result is the same visual sample Joel had, but using my live Flickr photos from my gallery.  This is made possible because Flickr has a) a REST api and b) a valid cross-domain policy file.  Both of these enable Silverlight to be a great client for consuming this data.  The visualization could be enhanced to provide mouse-over effects to zoom the picture I suppose, but I’ll get to that later.  Pretty fun that just a few changes (and none to XAML) enabled me to make this real for me.

    The code for my changes is here but note you must have your own Flickr API key from their site.  I also implemented supporting an initParams value so you can pass in the Flickr user name dynamically. 

    UPDATE: To use the initParams capability and display a badge for your Flickr account, you can use an <iframe> tag and point to http://silverlight.services.live.com/invoke/217/FlickrBadge/iframe.html?u=[yourflickrname] where the [yourflickrname] is the last part of your Flickr photos url.  For example if your account is at http://flickr.com/photos/uhoh_over than you would use http://silverlight.services.live.com/invoke/217/FlickrBadge/iframe.html?u=uhoh_over.

     


    This work is licensed under a Creative Commons Attribution By license.
  • NY Times Reader on Mac with Silverlight

    A while back the team at the New York Times newspaper produced a digital reader for their content, dubbed ‘Times Reader.’  The technology powering that reader experience (“the digital newspaper that reads like the real thing”) is Windows Presentation Foundation (WPF), part of the .NET Framework.  It is a remarkable experience for viewing digital news in a traditional format.  It provided online and offline reading capabilities mixed with some new and innovative ways of viewing related stories.

    Portions of the reader were even transformed into a starter kit framework: Syndicated Client Experiences Starter Kit.  This kit provides the initial plumbing to produce similar experiences and truly is a great starter kit to use.  Others like the Seattle PI and MSDN have put their content via this mechanism.

    This experience of the Times Reader was a Windows-only experience because of the dependency of the .NET Framework.  The Times Reader does provide the best experience because of this dependency however and it is important to note that.  Mac users, unfortunately, were left out.  Until now.

    Rob Larson, VP of Digital Production for the NY Times, announced that they’ve been working on a Mac version and a beta will be released soon.  Rob’s team implemented this version using Silverlight.

    “We are using Microsoft’s Silverlight technology to render the pages on the Mac version. Silverlight includes a subset of the Windows Presentation Foundation (WPF) tools we use on the PC version. This allows us to keep the look and feel of the Mac version very close to the PC version and also allows us to reuse code across platforms.”  source: http://firstlook.nytimes.com/?p=46

    I initially saw a lot of comments in the post about ‘why is this better’ and I think those are from people who haven’t seen the reader experience on the PC.  I have to admit that I’m not a newspaper reader at all, but as a geek, the news I do read is entirely digital…I’ve never owned a physical subscription to anything.  This digital reader experience is unique and fun to play around with (you have to see the search/related stories visualizations) and I think brings some freshness to traditional print news. 

    Rob’s post has more screenshots and details about the implementation and future plans, including a comment of their commitment to bring feature parity between the versions.  I’m looking forward to seeing this implemented and hearing from the development team about their use of Silverlight to bring this experience to the Mac platform.


    This work is licensed under a Creative Commons Attribution By license.
  • RIApalooza – I’ll be there!

    RIApalooza logo

    I’m very excited to have the opportunity to attend the RIApalooza event in Chicago in a few weeks (31 MAY).  What is RIApalooza?

    RIApalooza promises a platform agnostic and "PowerPoint-Free" zone, which means we are going to forgo the boring marketing pitches in favor of talking technology. RIApalooza is about creating Rich Internet Applications; how to go about building them and what is being built.  source: riapalooza.com

    I love the PPT-free zone aspect of it.  I loving having the maximum time to show some real working code, answer questions and see what everyone is working on.  I’ve decided to team up with a great designer, Corrina, where we will demonstrate some fun things.  It should be a great time.  I don’t want to give too much away, so if you are in the area, you should absolutely come.  You can register on the site, so be sure to do so.  I’ll be coming in on Friday and might need to do some fine tune prepping but would love to meet as many folks as possible at the meet-n-greet on Friday night.  Follow me on Twitter if you’d like and hopefully I’ll be able to post where the fun is happening.

    I look forward to seeing you there!


    This work is licensed under a Creative Commons Attribution By license.
  • SharePoint guide for Visual Studio Extensions released

    In February, the SharePoint team released a Visual Studio extensions kit for SharePoint development.  Just recently they released a user guide complete with samples and walkthroughs.  The sections include:

      • Starting out in SharePoint Development
      • Walkthrough of the VS extensions
      • Team Site project
      • Blank Site project
      • List Definition project
      • Web Part project
      • Workflow projects
      • Project Item Templates
      • Best practices for the VS extensions

    They also note that a VS2008 extensions release looks to be targeted for June 2008.  Paul Andrew has all the details with some snapshots on his blog post as well.


    This work is licensed under a Creative Commons Attribution By license.
  • Write Silverlight, win XBOX

    Want a Silverlight-branded XBOX console?  Yeah, me too, that would be cool.  Well, there isn’t one of those, but there is a chance for you to show your Silverlight prowess and win some cool stuff.

    The RIA development portal at DevX is currently running a contest (which ends next week, yikes, hurry!) for creating games in Silverlight 2.  The contest seems relatively simple:

    Step 1: Create wicked cool game in Silverlight 2
    Step 2: Host it on Silverlight Streaming

    How simple is that…oh yeah, except for the ‘creating game’ part.  There are a few places to help you get started creating games in Silverlight.  Check out the Silverlight Games 101 site which has some great posts and pointers to help in creating casual games. 

    The prizes are an XBOX 360 (sorry, not Silverlight branded), an 80GB Zune and a game bundle including Halo 3 and Mass Effect.

    So head over to the RIA Run site and get all the details to get submitted by 15 MAY!!!


    This work is licensed under a Creative Commons Attribution By license.
  • New and great Silverlight examples

    There are some really great application concepts emerging using Silverlight.  I cam across two that I feel are really demonstrating great use of the technology, both in the code as well as attention to detail in the user interface.  Both of these examples make great use of layouts, controls, etc. within Silverlight 2 to show what is possible with some imagination and the platform.

    The first is the “My Travel Management” site which leverages real travel information to represent the scenario of looking at flight arrangements.  It definitely is a twist on the Silverlight Airlines, providing a little more detail (and real information) about flights as well as unique visualizations on changing your travel parameters.  It uses somewhat of the Office 2007 ribbon style for creating user input options and then displays the results with what I think is a well done visualization of information.  Play around and you’ll see what I mean:

    The second is a newcomer demonstrating a user interface for a full-featured healthcare application.  The “Patient Journey Demonstrator” takes the concept of individual patient care and shows the lifecycle of a patient through the care process, providing views for physicians, secondary care, etc.  There is a lot going on in this demonstration and provides different perspectives on controlling layout, custom controls, map integration, media integration, you name it, this one pretty much has it!

    Great job to the teams who wrote these applications, keep the great work coming!


    This work is licensed under a Creative Commons Attribution By license.
  • Foxit PDF Previewer Security Update

    Hello readers!  If you are a Foxit user, please update your reader software to the latest version ASAP.  A recent exploit was found by a security research firm and Foxit turned around an update to their reader within 24 hours.  Bravo to the Foxit team for being very agile and getting this rectified.

    After some further research and discussion with the development team it was found that the ActiveX component used in the PDF Preview Handlers might also be vulnerable.  To reconcile this, Foxit has issued a patched (and updated) version of the ActiveX control for the preview handlers.  I have since patched  both the Vista and the XP versions accordingly and tested them on several Vista and XP SP2 machines accordingly.

    If you are using these and have installed them PRIOR to 07-MAY-2008), please take a moment to proceed with the following:

      1. Close any instance of Outlook 2007.
      2. Uninstall any versions of the Foxit PDF Preview Handler from your system.
      3. Download the latest version of the PDF Preview Handler (Vista or XP). 
      4. Install the latest version.

    Note: that the previous links have been updated with the patched versions as well just in case.

    That should do it!  If you find any issues, please report them to me.  Thanks again to Foxit for being responsive and aggressive in this manner and for their support of the PDF Preview Handlers.


    This work is licensed under a Creative Commons Attribution By license.
  • Streaming media in Windows Server for Silverlight

    When using media with Silverlight there are a few things that you should be aware of.  First, ensure that the media you are planning on using conforms to the VC-1 specification.  Your media files just need to then be accessible via streaming or http-based access for progressive downloads.

    The media files for progressive downloads can be anywhere: any web server, Amazon S3 storage, some HttpHandler, whatever – as long as they can be served.

    Streaming media is supported via Windows Media Services.  If you haven’t set this up before, there are a few things to note with regard to Silverlight and streaming content.  Most typical default setups of Windows Media streaming uses Real Time Streaming Protocol (RTSP).  It’s actually important to note that while RTSP is the visible configuration, it is actually the Real-time Transport Protocol that is responsible for delivering the bits of audio/video.  All of this might not matter to you, but cache it away for later if you wish.

    For setting up streaming services, I recommend using Windows Media Services 2008, which is a free add-on for Windows Server 2008 systems.  After installing this add-on, you’ll have the ability to set up publishing points and host streams of playlists or single files.  What I wanted to point out is one of the common gotchas with Silverlight and streaming in the current versions.

    After installing the services, if you start the control panel and highlight the server you will see some options.  Looking at the Properties tab you will see more options, and specifically I wanted to call attention to the ‘Control Protocol’ option.  By default the only enabled option is RTSP.  So basically your streams would respond to a mms://foo link for you and open in Windows Media Player or something that plays back that media.

    The problem is that a few people have emailed me about why certain streams don’t work, etc.  Some are for various resons, but some are because of this problem here.  I get a lot of ‘my stream plays in Windows Media Player but not in Silverlight’ questions.  Assuming all other factors are correct (see footnote here as well), the problem is likely that you don’t have HTTP-based streaming enabled.  Silverlight basically looks at the mms:// URI and translates that to get the stream over HTTP instead as that is the method supported in current versions.  You can see this if you put a sniffer on your web application to monitor the requests.  To fix this all you have to do is enable the HTTP control protocol on your server.  Keep in mind that if you are using a single server for multiple scenarios, the default port 80 might already be taken by IIS.  Right click on the HTTP control protocol and choose properties, then choose the IP addresses and/or the port you want it to operate on.  Save those settings and then enable the protocol.

    By doing this your streaming server will now also stream over HTTP as well as RTSP, thus enabling different scenarios, but specifically allowing you to use Silverlight to host your streaming content.  Windows Media Services is a great tool to host streaming content and is pretty fun to mess around with (as well as intuitive to setup new streams) creating new publishing points for media.

    Other Streaming Issues

    One of the other most common issues I see in my inbox is ‘my stream doesn’t work and yes it is streamed over HTTP.’  The most common problem with this is that your page hosting the Silverlight content is likely being viewed over a file:// protocol scheme and your MediaElement has an http:// scheme.  This is known as cross-scheme and is not allowed in Silverlight.  Open the page under an HTTP context and it should render fine as long as it is the same protocol.

    Have fun playing with this and hope this helps!


    This work is licensed under a Creative Commons Attribution By license.
  • Making use of your JSON data in Silverlight

    Wait! Don’t throw out your JSON services!

    The Situation

    You’ve made an investment in exposing some services for client script consumption.  Most likely if you did it in the past 2 years, that involved exposing your data as JSON formatted objects.

    What is JSON?
    It is a text-based, human-readable format for representing simple data structures and associative arrays (called objects)

    Perhaps a search service returns a list of people formatted using your custom “Person” object and you’ve been using this in your AJAX applications for a while now.  Maybe your JSON data looks something like this:

    [{"City":"Queen Creek","FirstName":"Tim","LastName":"Heuer",
    "Website":"http:\/\/timheuer.com\/blog\/"},
    {"City":"Portland","FirstName":"Scott","LastName":"Hanselman",
    "Website":"http:\/\/hanselman.com\/blog\/"},
    {"City":"Redmond","FirstName":"Scott","LastName":"Guthrie",
    "Website":"http:\/\/weblogs.asp.net\/scottgu"},
    {"City":"New Hampshire","FirstName":"Joe","LastName":"Stagner",
    "Website":"http:\/\/joestagner.net"},
    {"City":"Boston","FirstName":"Jesse","LastName":"Liberty",
    "Website":"http:\/\/silverlight.net\/blogs\/jesseliberty"}]

    If you squint long enough you can see that this represents what looks like an object that would have this structure:

    FirstName, LastName, City, Website

    You could consume this in a Javascript function or something in the client script of your web application and nicely iterate through the array of ‘Person’ types, using some human-readable code.

    But now you want Silverlight!  And you think to yourself that you need to completely re-write everything to return .NET objects, etc.  Well, not so fast.

    JSON Serialization

    Because Silverlight 2 supports managed code development, you have some tricks in your bag to leverage existing services that you might not want (or need) to re-write entirely or just right away.  Let’s use the simple example above and assume I now want to use that same service and the same data result in my Silverlight application.  For now let’s assume the endpoint to that service is something like http://foo/mypeople/js.  Most JSON services were a result of using some type of RESTful query model, so essentially your request would likely be a simple GET or POST.

    Using Silverlight 2 and the simple WebClient, we can easily get that information from that REST endpoint.

    WebClient proxy = new WebClient();
    proxy.OpenReadCompleted += new OpenReadCompletedEventHandler(proxy_OpenReadCompleted); 
    proxy.OpenReadAsync(new Uri("http://foo/mypeople/js"));

    Using WebClient, we essentially open a Stream (which is our endpoint) and get the data back.  You can learn more about WebClient and other services with Silverlight by watching my videos about web services and other HTTP-based communication.  Remembering that service calls in Silverlight 2 are asynchronous, we look at our ‘proxy_OpenReadCompleted’ event and could first get our result (with proper error checking of course) which is of type Stream:

    Stream strm = e.Result;

    Now with that stream (which is essentially the JSON data now), what do we do?  Enter DataContractJsonSerializer.  Remember, we have this available to us thanks to the CLR being in Silverlight 2.  Before we start to use this, however, our client application must be aware of the Type we plan to de-serialize it back into.  So in our Silverlight application we need to have that type defined as such:

    public class Person
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string City { get; set; }
        public string Website { get; set; }
    }

    Simple enough.  Now we can complete our asynch handler like this and our Stream is now converted into an enumerable type that we can bind, iterate or do whatever we need to with our data.

    void proxy_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
    {
        Stream strm = e.Result;
        DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(Person[]));
        Person[] ppl = (Person[])ser.ReadObject(strm);
    
        if (ppl.Length > 0)
        {
            // do something with the data
            // bind, interate, whatever
        }
    }

    That’s it!  With a few lines of code we’ve been able to re-use our JSON service and data from Silverlight.  This might not be the best idea in all of your scenarios but it is possible if you want to transition to other services or make re-use out of your investments already.

    A Word About WCF Script-enabled Services

    For some of you, if you were already a part of the WCF wave when you created your services, you may have already exposed them as scriptable services using an endpoint behavior that was enableWebScript.  This may have been working fine for you but if you look at the output of that, it might be adding some things that you may not need.  This is because it was intended for ASP.NET AJAX consumption (i.e., it adds “_type” and “_d” stuff).  This is easily rectified to make it a cleaner JSON result as well as make the messages smaller.

    By implementing the webHttpBehavior in conjunction with the webHttpBinding type for WCF, you will get a much cleaner/smaller JSON payload for your service.  When implementing this, you’ll want to decorate your service methods accordingly using the WebGet attributes:

    [OperationContract]
    [WebGet(UriTemplate="people", ResponseFormat=WebMessageFormat.Json)]
    Person[] GetListOfPeople();

    While I’d argue this isn’t completely necessary to use your existing services, it might make your type parsing a little cleaner and as noted, the message size smaller.  So using this (in fact my endpoint this whole time actually is a WCF webHttpBinding endpoint) the entire code looks something like this:

    public partial class Page : UserControl
    {
        public Page()
        {
            InitializeComponent();
            Loaded += new RoutedEventHandler(Page_Loaded);
        }
    
        void Page_Loaded(object sender, RoutedEventArgs e)
        {
            WebClient proxy = new WebClient();
            proxy.OpenReadCompleted += new OpenReadCompletedEventHandler(proxy_OpenReadCompleted); 
            proxy.OpenReadAsync(new Uri("http://localhost:34907/JsonData_Web/People.svc/people"));
        }
    
        void proxy_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
        {
            Stream strm = e.Result;
            DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(Person[]));
            Person[] ppl = (Person[])ser.ReadObject(strm);
    
            if (ppl.Length > 0)
            {
                
            }
        }
    }

    Easy enough.  If you want to know more about the WCF binding types and implementing full REST services in WCF, check out Rob Bagby’s blog…he has a lot of good material there.

    Summary

    If you have existing services that you’ve enabled JSON responses for already for use in AJAX applications, consider making re-use of them where appropriate.  This may bridge a transition to other WCF endpoints or other service-types while you are writing your Silverlight applications.

    I’ve included my sample project used here so you can tinker and you can download the code here.

    Hope this helps!


    This work is licensed under a Creative Commons Attribution By license.
  • Geek sounds, a classic keyboard

    My new team does a lot of video conferencing (I think ScottHa has a picture of our last meeting somewhere on the internets).  I’m still getting used to it a bit, and network latency gives me the willies when there is such a delay in audio or choppiness.  Nonetheless I like being able to “see” people, so I haven’t written it off just yet.

    My last 1:1 meeting with my boss also reminded me of geek sounds.  After talking about something he was going to fire off a message to another colleague to connect some dots.  So he paused and started typing.  I swear he uses this keyboard:

    I recorded a quick snippet for my own archives…I love the sound of a solid keyboard:

    It was too funny not to pass up, sorry Simon.