Skip to main content
Commonmark migration
Source Link

###Source

Source

###Source

Source

replaced http://stackapps.com/ with https://stackapps.com/
Source Link

As an example of how leveraging Soapi.CSSoapi.CS and the reusable controls in Soapi.Contrib.Silverlight can increase productivity when writing code against the API, I include the source code for the Soapi.Explore Silverlight application.

//  
//  Project: SOAPI
//  http://soapics.codeplex.com
//  httphttps://stackapps.com/questions/386
//  
//  Copyright 2010, Sky Sanders
//  Licensed under the GPL Version 2 license.
//  http://soapics.codeplex.com/license
//  
//  Date: Aug 12 2010 
//  API ver 1.0 rev 2010.0709.04
//  

#region

using System;
using System.Text.RegularExpressions;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using Amp.Controls.MouseWheel;
using Soapi;
using Soapi.Contrib.Controls;
using Soapi.Domain;
using Soapi.Net;
using Soapi.Parameters;
using Soapi.Routes;

#endregion

namespace Explore
{
    public partial class MainPage
    {
        #region Constants

        private const string ApiKey = "qgAq_KfDu0KYzlNG-qaTuw";

        #endregion

        #region Fields

        private TextBlock _busyMessage;

        private bool _cancel;

        private Button _cancelButton;

        private ApiContext _context;

        #endregion

        #region Constructors

        public MainPage()
        {
            InitializeComponent();
            InitializeContext();
        }

        private void InitializeContext()
        {
            BusyIndicator.IsBusy = true;
            BusyIndicator.DisplayAfter = new TimeSpan(0, 0, 0, 0, 500);
            ScrollViewerMouseWheelSupport.Initialize(this);
            AccordionScroller.AddMouseWheelSupport();
            JsonOutputScroller.AddMouseWheelSupport();
            RequestCache.Instance.DefaultDuration = new TimeSpan(0, 0, 0, 1);
            _context = new ApiContext(ApiKey);
            _context.Initialized += ContextInitialized;


            _context.Initialize(true);
        }

        void ContextInitialized(object sender, EventArgs e)
        {
            Dispatcher.BeginInvoke(() =>
                {
                    SitesComboBox.ItemsSource = _context.Sites;
                    SitesComboBox.SelectedIndex = 0;

                    // this is a total hack. need to use mvvm light and a command pattern.

                    WireUpRouteControl(AnswersById);
                    WireUpRouteControl(AnswersByIdComments);
                    WireUpRouteControl(Badges);
                    WireUpRouteControl(BadgesById);
                    WireUpRouteControl(BadgesName);
                    WireUpRouteControl(BadgesTags);
                    WireUpRouteControl(CommentsById);
                    WireUpRouteControl(PostsByIdComments);
                    WireUpRouteControl(Questions);
                    WireUpRouteControl(QuestionsById);
                    WireUpRouteControl(QuestionsByIdAnswers);
                    WireUpRouteControl(QuestionsByIdComments);
                    WireUpRouteControl(QuestionsByIdTimeline);
                    WireUpRouteControl(QuestionsUnanswered);
                    WireUpRouteControl(RevisionsById);
                    WireUpRouteControl(RevisionsByIdByRevisionGuid);
                    WireUpRouteControl(Search);
                    WireUpRouteControl(Stats);
                    WireUpRouteControl(Tags);
                    WireUpRouteControl(Users);
                    WireUpRouteControl(UsersById);
                    WireUpRouteControl(UsersByIdAnswers);
                    WireUpRouteControl(UsersByIdBadges);
                    WireUpRouteControl(UsersByIdComments);
                    WireUpRouteControl(UsersByIdCommentsTo);
                    WireUpRouteControl(UsersByIdFavorites);
                    WireUpRouteControl(UsersByIdMentioned);
                    WireUpRouteControl(UsersByIdQuestions);
                    WireUpRouteControl(UsersByIdReputation);
                    WireUpRouteControl(UsersByIdTags);
                    WireUpRouteControl(UsersByIdTimeline);
                    WireUpRouteControl(UsersModerators);
                    WireUpRouteControl(Sites);
                    WireUpRouteControl(UsersByIdAssociated);
                    BusyIndicator.IsBusy = false;
                });
        }

        #endregion

        #region Private Methods

        private void BusyMessageLoaded(object sender, RoutedEventArgs e)
        {
            _busyMessage = (TextBlock)sender;
        }

        private void CancelButtonClick(object sender, RoutedEventArgs e)
        {
            _cancel = true;
            _cancelButton.IsEnabled = false;
        }

        private void CancelButtonLoaded(object sender, RoutedEventArgs e)
        {
            _cancelButton = (Button)sender;
        }

        private void SetJsonText(string value, bool scroll)
        {
            JsonOutput.Text += value;
            if (scroll)
            {

                try
                {
                    JsonOutput.SelectionStart = JsonOutput.Text.LastIndexOf(Environment.NewLine);
                    JsonOutput.SelectionStart = JsonOutput.Text.LastIndexOf(Environment.NewLine, JsonOutput.SelectionStart);
                    JsonOutput.SelectionLength = 0;
                }
                catch
                {
                }
            }

        }
        private void SetUrl(IRoute route)
        {
            var url = Regex.Replace(route.RequestUri.AbsoluteUri, @"(\?|&)key=" + ApiKey, "");
            QueryUrl.Content = url;
            QueryUrl.NavigateUri = new Uri(url);
        }

        private void WireUpRouteControl(ParametersControl ctrl)
        {


            ctrl.ExecuteQuery += (s, e) =>
                {

                    IParameter parameters = ctrl.Parameters;
                    try
                    {
                        parameters.Validate();
                    }
                    catch (Exception ex)
                    {
                        Dispatcher.BeginInvoke(() =>
                            MessageBox.Show(ex.Message));

                        return;
                    }

                    var site = ((Site)SitesComboBox.SelectedItem);
                    var route = site.RouteFactory.GetRouteByPath(ctrl.Route);
                    route.Parameters = parameters;
                    var pagedRoute = route as IPagedRoute;
                    if (pagedRoute != null)
                    {
                        
                        var pageParameters = (IPageParameter)parameters;
                        if (pageParameters.PageCount < 1 || pageParameters.PageCount > 9)
                        {
                            var result =
                                MessageBox.Show(
                                    "Large result sets may be hard for your browser to handle.\r\nAre you sure you want to continue?"
                                    +"\r\n\r\nNote: I am working on a virtualized textbox\r\nthat will relieve this issue."
                                    , "Large Result Warning", MessageBoxButton.OKCancel);
                            if (result == MessageBoxResult.Cancel)
                            {
                                return;
                            }
                        }

                    }


                    Dispatcher.BeginInvoke(() =>
                        {
                            _cancelButton.IsEnabled = true;
                            BusyIndicator.IsBusy = true;
                            _busyMessage.Text = String.Format("Initializing request");
                            JsonOutput.Text = string.Empty;
                        });



                    ThreadPool.QueueUserWorkItem(ignored =>
                        {

                            if (pagedRoute != null)
                            {
                                pagedRoute.PageRecieved += (ss, ee) =>
                                    {
                                        Dispatcher.BeginInvoke(() =>
                                            {
                                                _busyMessage.Text = String.Format("Fetched Page {0} of {1}", ee.CurrentPage, ee.TotalPages);
                                                string value = "\r\n" + ee.Result.ResponseText;

                                                SetJsonText(value, false);
                                                SetUrl(route);
                                            });
                                        ee.Cancel = _cancel;
                                    };
                            }
                            try
                            {
#pragma warning disable 168
                                // need this to build structured response
                                var response = route.GetResponse();
#pragma warning restore 168
                                // todo - structured output of response
                                if (pagedRoute == null)
                                {
                                    Dispatcher.BeginInvoke(() =>
                                        {
                                            SetJsonText(route.ResponseText, false);
                                            SetUrl(route);
                                        });
                                }
                            }
                            catch (Exception ex)
                            {
                                Dispatcher.BeginInvoke(() =>
                                    {
                                        SetJsonText("\r\n--------------------------------------------------"
                                            + "\r\nERROR:"
                                            + "\r\n--------------------------------------------------\r\n"
                                            + ex.Message
                                            + "\r\n--------------------------------------------------\r\n"
                                            + ex
                                            + "\r\n--------------------------------------------------", true);
                                        SetUrl(route);
                                    });
                            }
                            finally
                            {
                                Dispatcher.BeginInvoke(() =>
                                    {
                                        _cancel = false;
                                        BusyIndicator.IsBusy = false;
                                    });
                            }
                        });
                };
        }

        #endregion

    }
}

As an example of how leveraging Soapi.CS and the reusable controls in Soapi.Contrib.Silverlight can increase productivity when writing code against the API, I include the source code for the Soapi.Explore Silverlight application.

//  
//  Project: SOAPI
//  http://soapics.codeplex.com
//  http://stackapps.com/questions/386
//  
//  Copyright 2010, Sky Sanders
//  Licensed under the GPL Version 2 license.
//  http://soapics.codeplex.com/license
//  
//  Date: Aug 12 2010 
//  API ver 1.0 rev 2010.0709.04
//  

#region

using System;
using System.Text.RegularExpressions;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using Amp.Controls.MouseWheel;
using Soapi;
using Soapi.Contrib.Controls;
using Soapi.Domain;
using Soapi.Net;
using Soapi.Parameters;
using Soapi.Routes;

#endregion

namespace Explore
{
    public partial class MainPage
    {
        #region Constants

        private const string ApiKey = "qgAq_KfDu0KYzlNG-qaTuw";

        #endregion

        #region Fields

        private TextBlock _busyMessage;

        private bool _cancel;

        private Button _cancelButton;

        private ApiContext _context;

        #endregion

        #region Constructors

        public MainPage()
        {
            InitializeComponent();
            InitializeContext();
        }

        private void InitializeContext()
        {
            BusyIndicator.IsBusy = true;
            BusyIndicator.DisplayAfter = new TimeSpan(0, 0, 0, 0, 500);
            ScrollViewerMouseWheelSupport.Initialize(this);
            AccordionScroller.AddMouseWheelSupport();
            JsonOutputScroller.AddMouseWheelSupport();
            RequestCache.Instance.DefaultDuration = new TimeSpan(0, 0, 0, 1);
            _context = new ApiContext(ApiKey);
            _context.Initialized += ContextInitialized;


            _context.Initialize(true);
        }

        void ContextInitialized(object sender, EventArgs e)
        {
            Dispatcher.BeginInvoke(() =>
                {
                    SitesComboBox.ItemsSource = _context.Sites;
                    SitesComboBox.SelectedIndex = 0;

                    // this is a total hack. need to use mvvm light and a command pattern.

                    WireUpRouteControl(AnswersById);
                    WireUpRouteControl(AnswersByIdComments);
                    WireUpRouteControl(Badges);
                    WireUpRouteControl(BadgesById);
                    WireUpRouteControl(BadgesName);
                    WireUpRouteControl(BadgesTags);
                    WireUpRouteControl(CommentsById);
                    WireUpRouteControl(PostsByIdComments);
                    WireUpRouteControl(Questions);
                    WireUpRouteControl(QuestionsById);
                    WireUpRouteControl(QuestionsByIdAnswers);
                    WireUpRouteControl(QuestionsByIdComments);
                    WireUpRouteControl(QuestionsByIdTimeline);
                    WireUpRouteControl(QuestionsUnanswered);
                    WireUpRouteControl(RevisionsById);
                    WireUpRouteControl(RevisionsByIdByRevisionGuid);
                    WireUpRouteControl(Search);
                    WireUpRouteControl(Stats);
                    WireUpRouteControl(Tags);
                    WireUpRouteControl(Users);
                    WireUpRouteControl(UsersById);
                    WireUpRouteControl(UsersByIdAnswers);
                    WireUpRouteControl(UsersByIdBadges);
                    WireUpRouteControl(UsersByIdComments);
                    WireUpRouteControl(UsersByIdCommentsTo);
                    WireUpRouteControl(UsersByIdFavorites);
                    WireUpRouteControl(UsersByIdMentioned);
                    WireUpRouteControl(UsersByIdQuestions);
                    WireUpRouteControl(UsersByIdReputation);
                    WireUpRouteControl(UsersByIdTags);
                    WireUpRouteControl(UsersByIdTimeline);
                    WireUpRouteControl(UsersModerators);
                    WireUpRouteControl(Sites);
                    WireUpRouteControl(UsersByIdAssociated);
                    BusyIndicator.IsBusy = false;
                });
        }

        #endregion

        #region Private Methods

        private void BusyMessageLoaded(object sender, RoutedEventArgs e)
        {
            _busyMessage = (TextBlock)sender;
        }

        private void CancelButtonClick(object sender, RoutedEventArgs e)
        {
            _cancel = true;
            _cancelButton.IsEnabled = false;
        }

        private void CancelButtonLoaded(object sender, RoutedEventArgs e)
        {
            _cancelButton = (Button)sender;
        }

        private void SetJsonText(string value, bool scroll)
        {
            JsonOutput.Text += value;
            if (scroll)
            {

                try
                {
                    JsonOutput.SelectionStart = JsonOutput.Text.LastIndexOf(Environment.NewLine);
                    JsonOutput.SelectionStart = JsonOutput.Text.LastIndexOf(Environment.NewLine, JsonOutput.SelectionStart);
                    JsonOutput.SelectionLength = 0;
                }
                catch
                {
                }
            }

        }
        private void SetUrl(IRoute route)
        {
            var url = Regex.Replace(route.RequestUri.AbsoluteUri, @"(\?|&)key=" + ApiKey, "");
            QueryUrl.Content = url;
            QueryUrl.NavigateUri = new Uri(url);
        }

        private void WireUpRouteControl(ParametersControl ctrl)
        {


            ctrl.ExecuteQuery += (s, e) =>
                {

                    IParameter parameters = ctrl.Parameters;
                    try
                    {
                        parameters.Validate();
                    }
                    catch (Exception ex)
                    {
                        Dispatcher.BeginInvoke(() =>
                            MessageBox.Show(ex.Message));

                        return;
                    }

                    var site = ((Site)SitesComboBox.SelectedItem);
                    var route = site.RouteFactory.GetRouteByPath(ctrl.Route);
                    route.Parameters = parameters;
                    var pagedRoute = route as IPagedRoute;
                    if (pagedRoute != null)
                    {
                        
                        var pageParameters = (IPageParameter)parameters;
                        if (pageParameters.PageCount < 1 || pageParameters.PageCount > 9)
                        {
                            var result =
                                MessageBox.Show(
                                    "Large result sets may be hard for your browser to handle.\r\nAre you sure you want to continue?"
                                    +"\r\n\r\nNote: I am working on a virtualized textbox\r\nthat will relieve this issue."
                                    , "Large Result Warning", MessageBoxButton.OKCancel);
                            if (result == MessageBoxResult.Cancel)
                            {
                                return;
                            }
                        }

                    }


                    Dispatcher.BeginInvoke(() =>
                        {
                            _cancelButton.IsEnabled = true;
                            BusyIndicator.IsBusy = true;
                            _busyMessage.Text = String.Format("Initializing request");
                            JsonOutput.Text = string.Empty;
                        });



                    ThreadPool.QueueUserWorkItem(ignored =>
                        {

                            if (pagedRoute != null)
                            {
                                pagedRoute.PageRecieved += (ss, ee) =>
                                    {
                                        Dispatcher.BeginInvoke(() =>
                                            {
                                                _busyMessage.Text = String.Format("Fetched Page {0} of {1}", ee.CurrentPage, ee.TotalPages);
                                                string value = "\r\n" + ee.Result.ResponseText;

                                                SetJsonText(value, false);
                                                SetUrl(route);
                                            });
                                        ee.Cancel = _cancel;
                                    };
                            }
                            try
                            {
#pragma warning disable 168
                                // need this to build structured response
                                var response = route.GetResponse();
#pragma warning restore 168
                                // todo - structured output of response
                                if (pagedRoute == null)
                                {
                                    Dispatcher.BeginInvoke(() =>
                                        {
                                            SetJsonText(route.ResponseText, false);
                                            SetUrl(route);
                                        });
                                }
                            }
                            catch (Exception ex)
                            {
                                Dispatcher.BeginInvoke(() =>
                                    {
                                        SetJsonText("\r\n--------------------------------------------------"
                                            + "\r\nERROR:"
                                            + "\r\n--------------------------------------------------\r\n"
                                            + ex.Message
                                            + "\r\n--------------------------------------------------\r\n"
                                            + ex
                                            + "\r\n--------------------------------------------------", true);
                                        SetUrl(route);
                                    });
                            }
                            finally
                            {
                                Dispatcher.BeginInvoke(() =>
                                    {
                                        _cancel = false;
                                        BusyIndicator.IsBusy = false;
                                    });
                            }
                        });
                };
        }

        #endregion

    }
}

As an example of how leveraging Soapi.CS and the reusable controls in Soapi.Contrib.Silverlight can increase productivity when writing code against the API, I include the source code for the Soapi.Explore Silverlight application.

//  
//  Project: SOAPI
//  http://soapics.codeplex.com
//  https://stackapps.com/questions/386
//  
//  Copyright 2010, Sky Sanders
//  Licensed under the GPL Version 2 license.
//  http://soapics.codeplex.com/license
//  
//  Date: Aug 12 2010 
//  API ver 1.0 rev 2010.0709.04
//  

#region

using System;
using System.Text.RegularExpressions;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using Amp.Controls.MouseWheel;
using Soapi;
using Soapi.Contrib.Controls;
using Soapi.Domain;
using Soapi.Net;
using Soapi.Parameters;
using Soapi.Routes;

#endregion

namespace Explore
{
    public partial class MainPage
    {
        #region Constants

        private const string ApiKey = "qgAq_KfDu0KYzlNG-qaTuw";

        #endregion

        #region Fields

        private TextBlock _busyMessage;

        private bool _cancel;

        private Button _cancelButton;

        private ApiContext _context;

        #endregion

        #region Constructors

        public MainPage()
        {
            InitializeComponent();
            InitializeContext();
        }

        private void InitializeContext()
        {
            BusyIndicator.IsBusy = true;
            BusyIndicator.DisplayAfter = new TimeSpan(0, 0, 0, 0, 500);
            ScrollViewerMouseWheelSupport.Initialize(this);
            AccordionScroller.AddMouseWheelSupport();
            JsonOutputScroller.AddMouseWheelSupport();
            RequestCache.Instance.DefaultDuration = new TimeSpan(0, 0, 0, 1);
            _context = new ApiContext(ApiKey);
            _context.Initialized += ContextInitialized;


            _context.Initialize(true);
        }

        void ContextInitialized(object sender, EventArgs e)
        {
            Dispatcher.BeginInvoke(() =>
                {
                    SitesComboBox.ItemsSource = _context.Sites;
                    SitesComboBox.SelectedIndex = 0;

                    // this is a total hack. need to use mvvm light and a command pattern.

                    WireUpRouteControl(AnswersById);
                    WireUpRouteControl(AnswersByIdComments);
                    WireUpRouteControl(Badges);
                    WireUpRouteControl(BadgesById);
                    WireUpRouteControl(BadgesName);
                    WireUpRouteControl(BadgesTags);
                    WireUpRouteControl(CommentsById);
                    WireUpRouteControl(PostsByIdComments);
                    WireUpRouteControl(Questions);
                    WireUpRouteControl(QuestionsById);
                    WireUpRouteControl(QuestionsByIdAnswers);
                    WireUpRouteControl(QuestionsByIdComments);
                    WireUpRouteControl(QuestionsByIdTimeline);
                    WireUpRouteControl(QuestionsUnanswered);
                    WireUpRouteControl(RevisionsById);
                    WireUpRouteControl(RevisionsByIdByRevisionGuid);
                    WireUpRouteControl(Search);
                    WireUpRouteControl(Stats);
                    WireUpRouteControl(Tags);
                    WireUpRouteControl(Users);
                    WireUpRouteControl(UsersById);
                    WireUpRouteControl(UsersByIdAnswers);
                    WireUpRouteControl(UsersByIdBadges);
                    WireUpRouteControl(UsersByIdComments);
                    WireUpRouteControl(UsersByIdCommentsTo);
                    WireUpRouteControl(UsersByIdFavorites);
                    WireUpRouteControl(UsersByIdMentioned);
                    WireUpRouteControl(UsersByIdQuestions);
                    WireUpRouteControl(UsersByIdReputation);
                    WireUpRouteControl(UsersByIdTags);
                    WireUpRouteControl(UsersByIdTimeline);
                    WireUpRouteControl(UsersModerators);
                    WireUpRouteControl(Sites);
                    WireUpRouteControl(UsersByIdAssociated);
                    BusyIndicator.IsBusy = false;
                });
        }

        #endregion

        #region Private Methods

        private void BusyMessageLoaded(object sender, RoutedEventArgs e)
        {
            _busyMessage = (TextBlock)sender;
        }

        private void CancelButtonClick(object sender, RoutedEventArgs e)
        {
            _cancel = true;
            _cancelButton.IsEnabled = false;
        }

        private void CancelButtonLoaded(object sender, RoutedEventArgs e)
        {
            _cancelButton = (Button)sender;
        }

        private void SetJsonText(string value, bool scroll)
        {
            JsonOutput.Text += value;
            if (scroll)
            {

                try
                {
                    JsonOutput.SelectionStart = JsonOutput.Text.LastIndexOf(Environment.NewLine);
                    JsonOutput.SelectionStart = JsonOutput.Text.LastIndexOf(Environment.NewLine, JsonOutput.SelectionStart);
                    JsonOutput.SelectionLength = 0;
                }
                catch
                {
                }
            }

        }
        private void SetUrl(IRoute route)
        {
            var url = Regex.Replace(route.RequestUri.AbsoluteUri, @"(\?|&)key=" + ApiKey, "");
            QueryUrl.Content = url;
            QueryUrl.NavigateUri = new Uri(url);
        }

        private void WireUpRouteControl(ParametersControl ctrl)
        {


            ctrl.ExecuteQuery += (s, e) =>
                {

                    IParameter parameters = ctrl.Parameters;
                    try
                    {
                        parameters.Validate();
                    }
                    catch (Exception ex)
                    {
                        Dispatcher.BeginInvoke(() =>
                            MessageBox.Show(ex.Message));

                        return;
                    }

                    var site = ((Site)SitesComboBox.SelectedItem);
                    var route = site.RouteFactory.GetRouteByPath(ctrl.Route);
                    route.Parameters = parameters;
                    var pagedRoute = route as IPagedRoute;
                    if (pagedRoute != null)
                    {
                        
                        var pageParameters = (IPageParameter)parameters;
                        if (pageParameters.PageCount < 1 || pageParameters.PageCount > 9)
                        {
                            var result =
                                MessageBox.Show(
                                    "Large result sets may be hard for your browser to handle.\r\nAre you sure you want to continue?"
                                    +"\r\n\r\nNote: I am working on a virtualized textbox\r\nthat will relieve this issue."
                                    , "Large Result Warning", MessageBoxButton.OKCancel);
                            if (result == MessageBoxResult.Cancel)
                            {
                                return;
                            }
                        }

                    }


                    Dispatcher.BeginInvoke(() =>
                        {
                            _cancelButton.IsEnabled = true;
                            BusyIndicator.IsBusy = true;
                            _busyMessage.Text = String.Format("Initializing request");
                            JsonOutput.Text = string.Empty;
                        });



                    ThreadPool.QueueUserWorkItem(ignored =>
                        {

                            if (pagedRoute != null)
                            {
                                pagedRoute.PageRecieved += (ss, ee) =>
                                    {
                                        Dispatcher.BeginInvoke(() =>
                                            {
                                                _busyMessage.Text = String.Format("Fetched Page {0} of {1}", ee.CurrentPage, ee.TotalPages);
                                                string value = "\r\n" + ee.Result.ResponseText;

                                                SetJsonText(value, false);
                                                SetUrl(route);
                                            });
                                        ee.Cancel = _cancel;
                                    };
                            }
                            try
                            {
#pragma warning disable 168
                                // need this to build structured response
                                var response = route.GetResponse();
#pragma warning restore 168
                                // todo - structured output of response
                                if (pagedRoute == null)
                                {
                                    Dispatcher.BeginInvoke(() =>
                                        {
                                            SetJsonText(route.ResponseText, false);
                                            SetUrl(route);
                                        });
                                }
                            }
                            catch (Exception ex)
                            {
                                Dispatcher.BeginInvoke(() =>
                                    {
                                        SetJsonText("\r\n--------------------------------------------------"
                                            + "\r\nERROR:"
                                            + "\r\n--------------------------------------------------\r\n"
                                            + ex.Message
                                            + "\r\n--------------------------------------------------\r\n"
                                            + ex
                                            + "\r\n--------------------------------------------------", true);
                                        SetUrl(route);
                                    });
                            }
                            finally
                            {
                                Dispatcher.BeginInvoke(() =>
                                    {
                                        _cancel = false;
                                        BusyIndicator.IsBusy = false;
                                    });
                            }
                        });
                };
        }

        #endregion

    }
}
Source Link
Sky Sanders
  • 12.1k
  • 3
  • 32
  • 60

###Source

As an example of how leveraging Soapi.CS and the reusable controls in Soapi.Contrib.Silverlight can increase productivity when writing code against the API, I include the source code for the Soapi.Explore Silverlight application.

//  
//  Project: SOAPI
//  http://soapics.codeplex.com
//  http://stackapps.com/questions/386
//  
//  Copyright 2010, Sky Sanders
//  Licensed under the GPL Version 2 license.
//  http://soapics.codeplex.com/license
//  
//  Date: Aug 12 2010 
//  API ver 1.0 rev 2010.0709.04
//  

#region

using System;
using System.Text.RegularExpressions;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using Amp.Controls.MouseWheel;
using Soapi;
using Soapi.Contrib.Controls;
using Soapi.Domain;
using Soapi.Net;
using Soapi.Parameters;
using Soapi.Routes;

#endregion

namespace Explore
{
    public partial class MainPage
    {
        #region Constants

        private const string ApiKey = "qgAq_KfDu0KYzlNG-qaTuw";

        #endregion

        #region Fields

        private TextBlock _busyMessage;

        private bool _cancel;

        private Button _cancelButton;

        private ApiContext _context;

        #endregion

        #region Constructors

        public MainPage()
        {
            InitializeComponent();
            InitializeContext();
        }

        private void InitializeContext()
        {
            BusyIndicator.IsBusy = true;
            BusyIndicator.DisplayAfter = new TimeSpan(0, 0, 0, 0, 500);
            ScrollViewerMouseWheelSupport.Initialize(this);
            AccordionScroller.AddMouseWheelSupport();
            JsonOutputScroller.AddMouseWheelSupport();
            RequestCache.Instance.DefaultDuration = new TimeSpan(0, 0, 0, 1);
            _context = new ApiContext(ApiKey);
            _context.Initialized += ContextInitialized;


            _context.Initialize(true);
        }

        void ContextInitialized(object sender, EventArgs e)
        {
            Dispatcher.BeginInvoke(() =>
                {
                    SitesComboBox.ItemsSource = _context.Sites;
                    SitesComboBox.SelectedIndex = 0;

                    // this is a total hack. need to use mvvm light and a command pattern.

                    WireUpRouteControl(AnswersById);
                    WireUpRouteControl(AnswersByIdComments);
                    WireUpRouteControl(Badges);
                    WireUpRouteControl(BadgesById);
                    WireUpRouteControl(BadgesName);
                    WireUpRouteControl(BadgesTags);
                    WireUpRouteControl(CommentsById);
                    WireUpRouteControl(PostsByIdComments);
                    WireUpRouteControl(Questions);
                    WireUpRouteControl(QuestionsById);
                    WireUpRouteControl(QuestionsByIdAnswers);
                    WireUpRouteControl(QuestionsByIdComments);
                    WireUpRouteControl(QuestionsByIdTimeline);
                    WireUpRouteControl(QuestionsUnanswered);
                    WireUpRouteControl(RevisionsById);
                    WireUpRouteControl(RevisionsByIdByRevisionGuid);
                    WireUpRouteControl(Search);
                    WireUpRouteControl(Stats);
                    WireUpRouteControl(Tags);
                    WireUpRouteControl(Users);
                    WireUpRouteControl(UsersById);
                    WireUpRouteControl(UsersByIdAnswers);
                    WireUpRouteControl(UsersByIdBadges);
                    WireUpRouteControl(UsersByIdComments);
                    WireUpRouteControl(UsersByIdCommentsTo);
                    WireUpRouteControl(UsersByIdFavorites);
                    WireUpRouteControl(UsersByIdMentioned);
                    WireUpRouteControl(UsersByIdQuestions);
                    WireUpRouteControl(UsersByIdReputation);
                    WireUpRouteControl(UsersByIdTags);
                    WireUpRouteControl(UsersByIdTimeline);
                    WireUpRouteControl(UsersModerators);
                    WireUpRouteControl(Sites);
                    WireUpRouteControl(UsersByIdAssociated);
                    BusyIndicator.IsBusy = false;
                });
        }

        #endregion

        #region Private Methods

        private void BusyMessageLoaded(object sender, RoutedEventArgs e)
        {
            _busyMessage = (TextBlock)sender;
        }

        private void CancelButtonClick(object sender, RoutedEventArgs e)
        {
            _cancel = true;
            _cancelButton.IsEnabled = false;
        }

        private void CancelButtonLoaded(object sender, RoutedEventArgs e)
        {
            _cancelButton = (Button)sender;
        }

        private void SetJsonText(string value, bool scroll)
        {
            JsonOutput.Text += value;
            if (scroll)
            {

                try
                {
                    JsonOutput.SelectionStart = JsonOutput.Text.LastIndexOf(Environment.NewLine);
                    JsonOutput.SelectionStart = JsonOutput.Text.LastIndexOf(Environment.NewLine, JsonOutput.SelectionStart);
                    JsonOutput.SelectionLength = 0;
                }
                catch
                {
                }
            }

        }
        private void SetUrl(IRoute route)
        {
            var url = Regex.Replace(route.RequestUri.AbsoluteUri, @"(\?|&)key=" + ApiKey, "");
            QueryUrl.Content = url;
            QueryUrl.NavigateUri = new Uri(url);
        }

        private void WireUpRouteControl(ParametersControl ctrl)
        {


            ctrl.ExecuteQuery += (s, e) =>
                {

                    IParameter parameters = ctrl.Parameters;
                    try
                    {
                        parameters.Validate();
                    }
                    catch (Exception ex)
                    {
                        Dispatcher.BeginInvoke(() =>
                            MessageBox.Show(ex.Message));

                        return;
                    }

                    var site = ((Site)SitesComboBox.SelectedItem);
                    var route = site.RouteFactory.GetRouteByPath(ctrl.Route);
                    route.Parameters = parameters;
                    var pagedRoute = route as IPagedRoute;
                    if (pagedRoute != null)
                    {
                        
                        var pageParameters = (IPageParameter)parameters;
                        if (pageParameters.PageCount < 1 || pageParameters.PageCount > 9)
                        {
                            var result =
                                MessageBox.Show(
                                    "Large result sets may be hard for your browser to handle.\r\nAre you sure you want to continue?"
                                    +"\r\n\r\nNote: I am working on a virtualized textbox\r\nthat will relieve this issue."
                                    , "Large Result Warning", MessageBoxButton.OKCancel);
                            if (result == MessageBoxResult.Cancel)
                            {
                                return;
                            }
                        }

                    }


                    Dispatcher.BeginInvoke(() =>
                        {
                            _cancelButton.IsEnabled = true;
                            BusyIndicator.IsBusy = true;
                            _busyMessage.Text = String.Format("Initializing request");
                            JsonOutput.Text = string.Empty;
                        });



                    ThreadPool.QueueUserWorkItem(ignored =>
                        {

                            if (pagedRoute != null)
                            {
                                pagedRoute.PageRecieved += (ss, ee) =>
                                    {
                                        Dispatcher.BeginInvoke(() =>
                                            {
                                                _busyMessage.Text = String.Format("Fetched Page {0} of {1}", ee.CurrentPage, ee.TotalPages);
                                                string value = "\r\n" + ee.Result.ResponseText;

                                                SetJsonText(value, false);
                                                SetUrl(route);
                                            });
                                        ee.Cancel = _cancel;
                                    };
                            }
                            try
                            {
#pragma warning disable 168
                                // need this to build structured response
                                var response = route.GetResponse();
#pragma warning restore 168
                                // todo - structured output of response
                                if (pagedRoute == null)
                                {
                                    Dispatcher.BeginInvoke(() =>
                                        {
                                            SetJsonText(route.ResponseText, false);
                                            SetUrl(route);
                                        });
                                }
                            }
                            catch (Exception ex)
                            {
                                Dispatcher.BeginInvoke(() =>
                                    {
                                        SetJsonText("\r\n--------------------------------------------------"
                                            + "\r\nERROR:"
                                            + "\r\n--------------------------------------------------\r\n"
                                            + ex.Message
                                            + "\r\n--------------------------------------------------\r\n"
                                            + ex
                                            + "\r\n--------------------------------------------------", true);
                                        SetUrl(route);
                                    });
                            }
                            finally
                            {
                                Dispatcher.BeginInvoke(() =>
                                    {
                                        _cancel = false;
                                        BusyIndicator.IsBusy = false;
                                    });
                            }
                        });
                };
        }

        #endregion

    }
}