Sharker Khaleed Mahmud Silverlight Tips & Tricks

January 9, 2011

94. Using the Bing API in Silverlight

Filed under: Silverlight — Tags: — Sharker Khaleed Mahmud | shamrat231 @ 2:22 AM

[tweetmeme source=”shamrat231” only_single=false]

The Version 2 of Bing API has cross domain policy…so now it can easily do Bing Search from silverlight app. In this entry, I will do a simple query search using the API applying MVVM pattern and ICommand.

You can see the live example here [live demo]

The SOURCE CODE(.zip) is at the end of the page for download.

Let look at the initial code

        public void Search(string query, ActionXElement>> searchCallBack)
        {
            string AppId = “—“; //API for http:// silverlightips.net site
            string _baseURI  = “http://api.search.live.net/xml.aspx?Appid={0}&query={1}&sources=web“;

            Uri address = new Uri(String.Format(_baseURI, AppId, query));

            WebClient service = new WebClient();
            service.OpenReadCompleted += (sender, e) => searchCallBack(GetResults(e));
            service.OpenReadAsync(address);
        }

As you can see I created a simple URI to do a API search. In here, the parameter that i am passing are appid, query text and the sources in the base uri. Just to give u the idea of the URI that is being created, i will debug it and put a snapshot below.

Copy the url and test paste it in the browser to check if the url works or not. Do note that our e.result should return exactly the same output as shown in the browser.

Our webclient should return exactly this. If you look in the above code, we are calling a method GetResults where we are returning the results as shown below.

        private XElement GetResults(OpenReadCompletedEventArgs e)
        {
            XElement element = null;

            if (e.Error == null)
            {
                if (e.Result != null)
                {
                    element = XElement.Load(XmlReader.Create(e.Result));
                }
            }

            return element;
        }

The above code returns the search result. The type of result that it give is stream type. To do LINQ queries on XML, I converted the result to XElement. So, the converted XElement result should be equivalent to the one the url I pasted before. Let debug and check it.

So we basically can see the result that it gives. So we can conclude the WebService part of the project is working. The web service is being invoked through a view model through an interface.

BingAPIViewModel.cs

    public class BingAPIViewModel
    {
        public ObservableCollection<SearchResult> Results { get; set; }
        public IAPIService APIService { get; set; }

        public BingAPIViewModel()
        {
            this.Results = new ObservableCollection<SearchResult>();
            this.APIService = new APIService();
            this.APIService.Search(“cricket”, this.OnSearchCompleted);
        }

        private void OnSearchCompleted(XElement searchResults)
        {
            this.Results.Clear();
        }
    }

Here the return type is XElement which is great for LINQ queries. Now lets create a simple Model for the return collection.

    public class SearchResult
    {
        public string Title { get; set; }
        public string Description { get; set; }
        public string UrL { get; set; }
    }

The main idea is now to iterate our collection of XElement and fill our Results of type Observablecollection which is done below.

        private void OnSearchCompleted(XElement elements)
        {
            this.Results.Clear();
            const string WEB_NS = “http://schemas.microsoft.com/LiveSearch/2008/04/XML/web“;
            IEnumerable<XNode> nodes = null;
            nodes = elements.Descendants(XName.Get(“Results”, WEB_NS)).Nodes();

            if (nodes.Count() > 0)
            {
                var results = from uris in nodes
                              select new SearchResult
                              {
                                  UrL = ((XElement)uris).Element(XName.Get(“Url”, WEB_NS)).Value,
                                  Title = ((XElement)uris).Element(XName.Get(“Title”, WEB_NS)).Value,
                                  Description = ((XElement)uris).Element(XName.Get(“Description”, WEB_NS)).Value,
                              };

                foreach (SearchResult result in results)
                {
                    Results.Add(result);
                }
            }
        }

Ok, we have received the search result into our view model. Now if we bind the view model to our view we can see the data. This can be easily done by this.

this.DataContext = new BingAPIViewModel(); at code and in UI

            <ListBox x:Name=”BingSearch” ItemsSource=”{Binding Results}” Style=”{Binding ListBoxStyle}”>
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel>
                        <HyperlinkButton Content=”{Binding Title}” NavigateUri=”{Binding Url}” TargetName=”blank” Height=”20″/>
                        <TextBlock Text=”{Binding Description}” HorizontalAlignment=”Stretch” TextWrapping=”Wrap” Width=”500″  />
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>

So far, we have used fixed variable for our query search. Now lets make it dynamic. For this I will use simple ICommand. Bind the button with an ICommand in view model.

and the modified view model using ICommand 

       public ICommand SearchCommand { get; set; }
        public IAPIService APIService { get; set; }
        private const string WEB_NS = “http://schemas.microsoft.com/LiveSearch/2008/04/XML/web“;

        public BingAPIViewModel()
        {
            this.Results = new ObservableCollection<SearchResult>();
            this.APIService = new APIService();
            this.SearchCommand = new DelegateCommand(this.SearchCommandChanged, this.CanInputTexChanged);
            this.APIService.Search(“sample”, this.OnSearchCompleted);
        }

        internal bool CanInputTexChanged(object param)
        {
            return true;
        }

        private void SearchCommandChanged(object param)
        {
            this.APIService.Search(param as string, this.OnSearchCompleted);
        }

As always, you can download the source code from here [download link]

Sharker Khaleed Mahmud
Web Developer

Older Posts »

Create a free website or blog at WordPress.com.