Posts Tagged with WCF

Silverlight how to: RSS feed stored as JSON in Isolated Storage

This week I was reading two of my favorite Microsoft Evangelist blogs; Kirk Allen Evans’ and Tim Heuer and was inspired to build upon two of their posts. Kirk wrote a great entry on Creating a JSON Service with WebGet and WCF 3.5 and Tim on
Calling web services with Silverlight 2. I thought it would be interesting to take the concepts covered in both of these posts and put them together into my own how to. In my sample I read an RSS feed into a JSON string, stores it in Isolated storage, and displays it in a ListBox. Once displayed, I will check every 30 seconds to see if the RSS feed has changed. Out-of-the-box my solution is not practical, but illustrates a flexible technique for caching a serialized collection of data in the event the service is unavailable.

In the first part of my sample I check to see if I have a cache of RSS in Isolated Storage. If so, I use the “DataContractJsonSerializer” class to de-serialize the JSON array. Once de-serialized, I can bind it to my ListBox control in “Page.xaml”

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
void Page_Loaded(object sender, RoutedEventArgs e)
{
    RssService.RssItem[] items
    if (_isf.FileExists("blog.json"))
    {
        //Read from IsolatedStorage the last set of blog entires
        using (IsolatedStorageFileStream isfs = 
         new IsolatedStorageFileStream("blog.json", System.IO.FileMode.Open, _isf))
        {
            //Deserialize the JSON array that was stored in Isolated storage.
            DataContractJsonSerializer djson = 
             new DataContractJsonSerializer(typeof(RssService.RssItem[]))
 
            items = djson.ReadObject(isfs) as RssService.RssItem[]
 
            isfs.Position = 0
            using (StreamReader sr = new StreamReader(isfs))
            {
                this.txtBlock.Text = sr.ReadToEnd()
            }
            isfs.Close()
        }
        listBox.ItemsSource = items
    }
 
    . . . . . . 
}

After we update our presentation of RSS, I will insert a animating UserControl to be use when we go to retrieve additional RSS items. This retrieval from our WCF 3.5 service will be executed every 10 seconds when our “DispatcherTimer” fires.

1
2
3
4
5
6
7
8
9
10
11
12
    //insert a UserControl that animates a spinner when we are retrieving 
    //an update of RSS data
    _indicator.HorizontalAlignment = HorizontalAlignment.Center
    _indicator.VerticalAlignment = VerticalAlignment.Center
    this.LayoutRoot.Children.Add(_indicator)
    _indicator.Visibility = Visibility.Collapsed
 
    //we will use a timer here to simulate a 5 second delay in grabbing 
    //the next rss update
    _dt.Interval = new TimeSpan(0, 0, 10)
    _dt.Tick += new EventHandler(_dt_Tick)
    _dt.Start()

Upon successful retrieval from our WCF service, we will update our isolated storage by serializing our array of RssItems[] into JSON, and writing that text to a file.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
void wcf_GetFeedsCompleted(object sender, 
    IsolatedStorage.RssService.GetFeedsCompletedEventArgs e)
{
    try
    {
        RssService.RssItem[] items = e.Result as RssService.RssItem[]
        //if we were able to grab a new set of Rss items then update Isolated storage
        if (items.Length > 0)
        {
            if (_isf.FileExists("blog.json"))
            {
                _isf.DeleteFile("blog.json")
            }
            using (IsolatedStorageFileStream isfs = 
             new IsolatedStorageFileStream("blog.json", System.IO.FileMode.Create, _isf))
            {
                //Take the array of RssItem[] objects and convert it to a JSON array.
                DataContractJsonSerializer djson = new DataContractJsonSerializer(items.GetType())
                MemoryStream ms = new MemoryStream()
                djson.WriteObject(ms, items)
 
                this.txtBlock.Text = System.Text.Encoding.UTF8.GetString
                   (ms.GetBuffer(), 0, Convert.ToInt16(ms.Length))
 
                isfs.Write(ms.GetBuffer(), 0, Convert.ToInt16(ms.Length))
                isfs.Close()
            }
            listBox.ItemsSource = items
        }
        this.listBox.Opacity = 1
        _indicator.Animation.Stop()
        _indicator.Visibility = Visibility.Collapsed
    }
    catch (Exception ex)
    {
        this.txtBlock.Text = ex.Message
    }
}

Thanks again to Tim and Kirk for the majority of my example.

Code: IsolatedStorage.zip