C# REST Sample Code

View Demo / Source Code

The following code snippets are taken from the Decibel WPF REST API Demo.

WPF Source Code WPF Binary

Silverlight Source Code View Online

The code snippets will guide you through some basic use case scenarios of the Decibel REST API.

Calling the API

The WebClient class in the System.Net namespace provides methods for receiving data from a resource identified by a URI.

The Rest API is stateless, which means you need to identify yourself with each call.

The WebClient instance does not send optional HTTP headers by default. On each call to the API you will need an Application ID, Application Key and Timestamp included in your HTTP request header. To make this easier a function called SetDecibelRequestHeaders(WebClient, AppID, AppKey) is defined in the Util.cs class.

The following code example sets the WebClient request headers.

WebClient client = new WebClient();
client.Headers.Add("DecibelAppID", {Your Application ID});
client.Headers.Add("DecibelAppKey", {Your Application Key});
client.Headers.Add("DecibelTimestamp", DateTime.Now.ToString("yyyyMMdd HH:mm:ss", System.Globalization.CultureInfo.InvariantCulture));

The DownloadStringAsync(Uri) method downloads a String from a resource, without blocking the calling thread. This enables the application to continue doing useful work while the method call runs.

The DownloadStringCompleted event is raised each time an asynchronous operation to download a resource as a string completes. The DownloadStringCompletedEventArgs class provides the event handler with event data.

The following code example request albums by artist name and stores the XML response.

WebClient client = new WebClient();
Util.SetDecibelRequestHeaders(client, "<Your Application ID>", "<Your Application Key>");
client.DownloadStringCompleted += client_DownloadStringCompleted;
client.DownloadStringAsync(new Uri("http://api.decibel.net/v1/Albums/?artist=miles%20davis&format=xml"));
 
private void client_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
    string result;
    if(e.Error == null)
        result = e.Result;
}

Deserialization

The Decibel REST API returns data in two formats XML and JSON. To make it easier to parse the response the data can be deserialized into manageable objects.

To deserialize the Decibel REST API responses you will need to add the QueryResultHolder.cs file to your project. This file contains the class definitions for the different types of objects which can be requested from the API.

  • Right click on the project name in the Solution Explorer
  • Select add new folder and name this Models
  • Download the QueryResultHolder.cs class (Right click and select Save link as...)
  • Right click on the Models namespace folder and select Add Existing Item...
  • Select the QueryResultHolder.cs file and click Add

XML Deserialization

The XmlSerializer class in the System.Xml.Serialization namespace enables you to deserialize XML documents into objects of a specified type. It should be constructed with the type of the object that will be deserialized. The typeof operator is used to obtain the System.Type object for a type.

The following code example deserializes the XML response from a Albums API call to a AlbumQueryResult object.

private void client_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
    if (e.Error == null)
    {
        AlbumQueryResult queryResult;
        XmlSerializer serializer = new XmlSerializer(typeof(AlbumQueryResult));
        using (TextReader reader = new StringReader(e.Result))
        {
            queryResult = (AlbumQueryResult)(serializer.Deserialize(reader));
        }
    }
}

To make it easier to deserialize the different types of XML response objects a generic function is defined in the Util.cs class included with the sample project.

The following example code deserializes a Tracks API call to a TrackQueryResult object.

TrackQueryResult queryResult = Util.DeserializeXmlString<TrackQueryResult>(e.Result);

JSON Deserialization

The JavaScriptSerializer in the System.Web.Script.Serialization.JavaScriptSerializer namepsace enables you to deserialize JSON documents into objects of a specified type.

You will need to add a reference to the System.Web.Extensions assembly before using the JavaScriptSerializer class.

  • Right click on the References folder in the Solution Explorer
  • Select Add Reference...
  • Select Assemblies and locate the System.Web.Extension assembly
  • Click on the check box next to the assembly name and click OK

The following code example deserializes the JSON response from a Tracks API call to a TrackQueryResult object.

private void client_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
    if(e.Error == null)
        TrackQueryResult queryResult = new JavaScriptSerializer().Deserialize<TrackQueryResult>(e.Result);
}

Albums: Search for albums by title

private void BeginAlbumSearch(string albumTitle, string applicationID, string applicationKey)
{
    // Construct the WebClient and set the request headers
    WebClient client = new WebClient();
    client.Encoding = Encoding.UTF8;
    client.Headers.Add("DecibelAppID", applicationID);
    client.Headers.Add("DecibelAppKey", applicationKey);
    client.Headers.Add("DecibelTimestamp", DateTime.Now.ToString("yyyyMMdd HH:mm:ss", 
        System.Globalization.CultureInfo.InvariantCulture));
 
    // Set the callback function which is invoked when the download of the resource completes
    client.DownloadStringCompleted += client_AlbumSearchCompleted;
 
    // Issue the request to the Decibel Web Service
    client.DownloadStringAsync(new Uri("http://api.decibel.net/v1/Albums/?albumTitle=" + albumTitle + 
        "&format=json"));
}
 
private void client_AlbumSearchCompleted(object sender, DownloadStringCompletedEventArgs e)
{
    if (e.Error == null) 
    {
        // Deserialize the response
        // You will need to add a reference to the System.Web.Extensions assembly
        AlbumQueryResult queryResult = new JavaScriptSerializer().Deserialize<AlbumQueryResult>(e.Result);
 
        // Display the results in a grid
        dtgResults.ItemsSource = queryResult.ResultSet;
    }
    else
    {
        MessageBox.Show("The Decibel Web Service request was not successful due to the following error:" + 
            Environment.NewLine + e.Error.ToString());
    }
}

Albums: Retrieve Albums with Track information

private void BeginAlbumRetrieve(string albumID, string applicationID, string applicationKey)
{
    // Construct the WebClient and set the request headers
    WebClient client = new WebClient();
    client.Encoding = Encoding.UTF8;
    client.Headers.Add("DecibelAppID", applicationID);
    client.Headers.Add("DecibelAppKey", applicationKey);
    client.Headers.Add("DecibelTimestamp", DateTime.Now.ToString("yyyyMMdd HH:mm:ss", 
        System.Globalization.CultureInfo.InvariantCulture));
 
    // Set the callback function which is invoked when the download of the resource completes
    client.DownloadStringCompleted += client_AlbumRetrieveCompleted;
 
    // Issue the request to the Decibel Web Service
    string depth = "Tracks;ImageThumbnail;Media;Names;ExternalIdentifiers;Genres;Publications;Performances;";
    client.DownloadStringAsync(new Uri("http://api.decibel.net/v1/Albums/" + "?depth=" + depth + "&id=" + 
        albumID + "&format=json"));
}
 
private void client_AlbumRetrieveCompleted(object sender, DownloadStringCompletedEventArgs e)
{
    if (e.Error == null)
    {
        // Deserialize the response
        AlbumQueryResult queryResult = new JavaScriptSerializer().Deserialize<AlbumQueryResult>(e.Result);
 
        // Display the album information
        Album album = queryResult.ResultSet[0];
        txtName.Text = album.Name;
        txtArtists.Text = album.Artists;
        txtDiscs.Text = album.DiscCount.ToString();
        txtTracks.Text = album.TrackCount.ToString();
        txtDuration.Text = Util.FormatTime(Convert.ToInt32(album.TotalSeconds));
        if (album.Discs != null && album.Discs.Length > 0 && album.Discs[0].MusicMedium != null)
            txtFormat.Text = album.Discs[0].MusicMedium.Name;
        if (album.ReleaseDate != null)
            txtReleaseDate.Text = album.ReleaseDate.Name;
        if (album.Publications != null && album.Publications.Length > 0)
            txtCatalogue.Text = album.Publications[0].CatalogueNumber;
        if (album.Publications != null && album.Publications.Length > 0)
            txtPublisher.Text = album.Publications[0].Publisher.Name;
        if (album.Genres != null)
        {
            foreach (GenreValue genreValue in album.Genres)
            {
                if (genreValue.Genre != null)
                    txtGenres.Text += genreValue.Genre.Name + ", ";
            }
        }
        if (album.GeoEntities != null)
        {
            foreach (GeoEntityValue genreEntityValue in album.GeoEntities)
            {
                if (genreEntityValue.GeoEntity != null)
                    txtRegion.Text += genreEntityValue.GeoEntity.Name + ", ";
            }
        }
        if (album.ExternalIdentifiers != null)
        {
            foreach (ExternalIdentifier externalIdentifier in album.ExternalIdentifiers)
            {
                ExternalDatabase externalDatabase = externalIdentifier.ExternalDatabase;
                if (externalDatabase.Name.Equals("UPC Barcode"))
                {
                    txtBarcode.Text = externalIdentifier.Identifier;
                    break;
                }
            }
        }
        imgThumbnail.Source = Util.GetImageSourceFromByteArray(album.Thumbnail);
        
        // Add the tracks to a list
        if (album.Tracks != null)
        {
            foreach (Track track in album.Tracks)
            {
                string trackInfo = track.SequenceNo + ") " + track.Name;
                if (track.TotalSeconds > 0)
                    trackInfo += " (" + Util.FormatTime(Convert.ToInt32(track.TotalSeconds)) + ")";
                lstTracks.Items.Add(trackInfo);
            }
        }
    }
    else
    {
        MessageBox.Show("The Decibel Web Service request was not successful due to the following error:" + 
            Environment.NewLine + e.Error.ToString());
    }
}

Download XAML

Albums: Get Album Cover Art

private void BeginAlbumArtRetrieve(string albumID, string applicationID, string applicationKey)
{
    // Construct the WebClient and set the request headers
    WebClient client = new WebClient();
    client.Encoding = Encoding.UTF8;
    client.Headers.Add("DecibelAppID", applicationID);
    client.Headers.Add("DecibelAppKey", applicationKey);
    client.Headers.Add("DecibelTimestamp", DateTime.Now.ToString("yyyyMMdd HH:mm:ss",
        System.Globalization.CultureInfo.InvariantCulture));
 
    // Set the callback function which is invoked when the download of the resource completes
    client.DownloadDataCompleted += client_AlbumArtRetrieveCompleted;
 
    // Issue the request to the Decibel Web Service
    client.DownloadDataAsync(new Uri("http://api.decibel.net/v1/Albums/" + albumID + "/Image"), albumID);
}
 
private void client_AlbumArtRetrieveCompleted(object sender, DownloadDataCompletedEventArgs e)
{
    if (e.Error == null)
    {
        if (e.Result == null)
        {
            MessageBox.Show(string.Format("Covert Art for Album with ID '{0}' could not be found.", e.UserState));
            return;
        }
 
        // Successfully retrieved the album cover art - display it on screen
        imgAlbumArt.Source = Util.GetImageSourceFromByteArray(e.Result);
    }
    else
    {
        MessageBox.Show("The Decibel Web Service request was not successful due to the following error:" + 
            Environment.NewLine + e.Error.ToString());
    }
}

AutoComplete: Request autocomplete suggestions

private void txtArtistName_KeyUp(object sender, KeyEventArgs e)
{
    if (e.Key != Key.Down && e.Key != Key.Up)
        BeginAutoCompleteRequest(txtArtistName.Text, "Participants");
}
 
private void txtAlbumTitle_KeyUp(object sender, KeyEventArgs e)
{
    if (e.Key != Key.Down && e.Key != Key.Up)
        BeginAutoCompleteRequest(txtAlbumTitle.Text, "Albums");
}
 
private void txtTrackTitle_KeyUp(object sender, KeyEventArgs e)
{
    if (e.Key != Key.Down && e.Key != Key.Up)
        BeginAutoCompleteRequest(txtTrackTitle.Text, "Tracks");
}
 
public void BeginAutoCompleteRequest(string text, string dictionary)
{
    // Construct the WebClient and set the request headers
    WebClient client = new WebClient();
    client.Encoding = Encoding.UTF8;
    client.Headers.Add("DecibelAppID", "<Your application ID>");
    client.Headers.Add("DecibelAppKey", "<Your application key>");
    client.Headers.Add("DecibelTimestamp", DateTime.Now.ToString("yyyyMMdd HH:mm:ss", 
        System.Globalization.CultureInfo.InvariantCulture));
 
    // Set the callback function which is invoked when the download of the resource completes
    client.DownloadStringCompleted += client_AutoCompleteRequestCompleted;
 
    // Issue the request to the Decibel Web Service
    client.DownloadStringAsync(new Uri("http://api.decibel.net/v1/AutoComplete?text=" + text + "&dictionary=" + 
        dictionary + "&limit=5" + "&format=json"), dictionary);
}
 
private void client_AutoCompleteRequestCompleted(object sender, DownloadStringCompletedEventArgs e)
{
    try
    {
        // Deserialize the response 
        SuggestionQueryResult queryResult;
        queryResult = new JavaScriptSerializer().Deserialize<SuggestionQueryResult>(e.Result);
 
        // Select the autocomplete dictionary
        List<string> suggestions = new List<string>();
        if (e.UserState.Equals("Participants"))
        {
            // Add the suggestion values to a list
            foreach (Suggestion suggestion in queryResult.Participants)
                suggestions.Add(suggestion.SuggestionValue);
            
            // Set the AutoCompleteBox ItemSource to the suggestion list
            txtArtistName.ItemsSource = suggestions; 
        }              
        else if (e.UserState.Equals("Albums"))
        {
            foreach (Suggestion suggestion in queryResult.Albums)
                suggestions.Add(suggestion.SuggestionValue);
            txtAlbumTitle.ItemsSource = suggestions;
        }
        else if (e.UserState.Equals("Tracks"))
        {
            foreach (Suggestion suggestion in queryResult.Tracks)
                suggestions.Add(suggestion.SuggestionValue);
            txtTrackTitle.ItemsSource = suggestions;
        }
    }
    catch { }
}

Download required WPF Toolkit libraries

Participants: Search for participants by name

private void BeginParticipantSearch(string participantName, string applicationID, string applicationKey)
{
    // Construct the WebClient and set the request headers
    WebClient client = new WebClient();
    client.Encoding = Encoding.UTF8;
    client.Headers.Add("DecibelAppID", applicationID);
    client.Headers.Add("DecibelAppKey", applicationKey);
    client.Headers.Add("DecibelTimestamp", DateTime.Now.ToString("yyyyMMdd HH:mm:ss", 
        System.Globalization.CultureInfo.InvariantCulture));
 
    // Set the callback function which is invoked when the download of the resource completes
    client.DownloadStringCompleted += client_ParticipantSearchCompleted;
 
    // Issue the request to the Decibel Web Service
    client.DownloadStringAsync(new Uri("http://api.decibel.net/v1/Participants/?name=" + participantName + 
        "&format=json"));
}
 
private void client_ParticipantSearchCompleted(object sender, DownloadStringCompletedEventArgs e)
{
    if (e.Error == null) 
    {
        // Store the query result
        ParticipantQueryResult queryResult = 
            new JavaScriptSerializer().Deserialize<ParticipantQueryResult>(e.Result);
        // Display the results in a grid
        dtgResults.ItemsSource = queryResult.ResultSet;
    }
    else
    {
        MessageBox.Show("The Decibel Web Service request was not successful due to the following error:" + 
            Environment.NewLine + e.Error.ToString());
    }
}

Participants: Retrieve participant with associations and track appearances

private void BeginParticipantRetrieve(string participantID, string applicationID, string applicationKey)
{
    // Construct the WebClient and set the request headers
    WebClient client = new WebClient();
    client.Encoding = Encoding.UTF8;
    client.Headers.Add("DecibelAppID", applicationID);
    client.Headers.Add("DecibelAppKey", applicationKey);
    client.Headers.Add("DecibelTimestamp", DateTime.Now.ToString("yyyyMMdd HH:mm:ss", 
        System.Globalization.CultureInfo.InvariantCulture));
 
    // Set the callback function which is invoked when the download of the resource completes
    client.DownloadStringCompleted += client_ParticipantRetrieveCompleted;
 
    // Issue the request to the Decibel Web Service
    string depth = "Names;GroupMembers;Nationalities;GeographicAreas;Annotations;ChartsAwards;Relationships;";
    client.DownloadStringAsync(new Uri("http://api.decibel.net/v1/Participants/" + "?depth=" + depth + 
        "&id=" + participantID + "&format=json"));
}
 
private void client_ParticipantRetrieveCompleted(object sender, DownloadStringCompletedEventArgs e)
{
    if (e.Error == null)
    {
        // Deserialize the response
        ParticipantQueryResult queryResult 
            = new JavaScriptSerializer().Deserialize<ParticipantQueryResult>(e.Result);
 
        // Display the participant information
        Participant participant = queryResult.ResultSet[0];
        txtName.Text = participant.Name;
        txtGender.Text = participant.Gender.ToString();
        txtDateBorn.Text = participant.DateBorn.Name;
        txtDateDied.Text = participant.DateDied.Name;
        txtPlaceBorn.Text = participant.PlaceBorn.Name;
        txtPlaceDied.Text = participant.PlaceDied.Name;
        chkIsGroup.IsChecked = participant.IsGroup;
        chkIsNonPerson.IsChecked = participant.IsNonPerson;
        chkIsGroup.IsChecked = participant.IsCharacter;
    }
    else
    {
        MessageBox.Show("The Decibel Web Service request was not successful due to the following error:" + 
            Environment.NewLine + e.Error.ToString());
    }
}
 
private void BeginParticipantAssociates(string participantID, string applicationID, string applicationKey)
{
    // Construct the WebClient and set the request headers
    WebClient client = new WebClient();
    client.Encoding = Encoding.UTF8;
    client.Headers.Add("DecibelAppID", applicationID);
    client.Headers.Add("DecibelAppKey", applicationKey);
    client.Headers.Add("DecibelTimestamp", DateTime.Now.ToString("yyyyMMdd HH:mm:ss", 
        System.Globalization.CultureInfo.InvariantCulture));
 
    // Set the callback function which is invoked when the download of the resource completes
    client.DownloadStringCompleted += client_ParticipantAssociatesCompleted;
 
    // Issue the request to the Decibel Web Service
    string depth = "Names;GroupMembers;Nationalities;GeographicAreas;Annotations;ChartsAwards;Relationships;";
    client.DownloadStringAsync(new Uri("http://api.decibel.net/v1/Participants/" + participantID + "/Associates" + 
        "?depth=" + depth + "&format=json"));
}
 
private void client_ParticipantAssociatesCompleted(object sender, DownloadStringCompletedEventArgs e)
{
    if (e.Error == null)
    {
        // Deserialize the response
        ParticipantAssociateQueryResult queryResult 
            = new JavaScriptSerializer().Deserialize<ParticipantAssociateQueryResult>(e.Result);
        
        // Display the participant associates in a list
        ParticipantAssociate[] associates = queryResult.ResultSet;
        foreach (ParticipantAssociate participantAssociate in associates)
            lstAssociates.Items.Add(participantAssociate.Participant.Name);
    }
    else
    {
        MessageBox.Show("The Decibel Web Service request was not successful due to the following error:" + 
            Environment.NewLine + e.Error.ToString());
    }
}
 
private void BeginParticipantTrackAppearances(string participantID, string applicationID, string applicationKey)
{
    // Construct the WebClient and set the request headers
    WebClient client = new WebClient();
    client.Encoding = Encoding.UTF8;
    client.Headers.Add("DecibelAppID", applicationID);
    client.Headers.Add("DecibelAppKey", applicationKey);
    client.Headers.Add("DecibelTimestamp", DateTime.Now.ToString("yyyyMMdd HH:mm:ss", 
        System.Globalization.CultureInfo.InvariantCulture));
 
    // Set the callback function which is invoked when the download of the resource completes
    client.DownloadStringCompleted += client_ParticipantTrackAppearancesCompleted;
 
    // Issue the request to the Decibel Web Service           
    string depth = "Names;GroupMembers;Nationalities;GeographicAreas;Annotations;ChartsAwards;Relationships;";
    client.DownloadStringAsync(new Uri("http://api.decibel.net/v1/Participants/" + participantID + "/Tracks" + 
        "?depth=" + depth + "&format=json"));      
}
 
private void client_ParticipantTrackAppearancesCompleted(object sender, DownloadStringCompletedEventArgs e)
{
    if (e.Error == null)
    {
        // Deserialize the response
        ParticipantTrackAppearanceQueryResult queryResult 
            = new JavaScriptSerializer().Deserialize<ParticipantTrackAppearanceQueryResult>(e.Result);
        TrackAppearance[] trackAppearances = queryResult.ResultSet;
        
        // Initialize the data table
        DataTable dataTable = new DataTable();
        dataTable.Columns.Add("Index", typeof(int));
        dataTable.Columns.Add("TrackName", typeof(string));
        dataTable.Columns.Add("AlbumName", typeof(string));
        dataTable.Columns.Add("ActivityName", typeof(string));
        int index = 1;
        foreach (TrackAppearance trackAppearance in queryResult.ResultSet)
        {
            DataRow dataRow = dataTable.NewRow();
            dataRow["Index"] = index;
            dataRow["TrackName"] = trackAppearance.TrackName;
            dataRow["AlbumName"] = trackAppearance.AlbumName;
            dataRow["ActivityName"] = trackAppearance.ActivityName;
            dataTable.Rows.Add(dataRow);
            index++;
        }
 
        // Display the track appearances in a grid
        dtgTrackAppearances.IsReadOnly = true;
        dtgTrackAppearances.ItemsSource = dataTable.AsDataView();
    }
    else
    {
        MessageBox.Show("The Decibel Web Service request was not successful due to the following error:" + 
            Environment.NewLine + e.Error.ToString());
    }
}

Download XAML

Tracks: Search for tracks by title

private void BeginTrackSearch(string trackTitle, string applicationID, string applicationKey)
{
    // Construct the WebClient and set the request headers
    WebClient client = new WebClient();
    client.Encoding = Encoding.UTF8;
    client.Headers.Add("DecibelAppID", applicationID);
    client.Headers.Add("DecibelAppKey", applicationKey);
    client.Headers.Add("DecibelTimestamp", DateTime.Now.ToString("yyyyMMdd HH:mm:ss", 
        System.Globalization.CultureInfo.InvariantCulture));
 
    // Set the callback function which is invoked when the download of the resource completes
    client.DownloadStringCompleted += client_TrackSearchCompleted;
 
    // Issue the request to the Decibel Web Service
    client.DownloadStringAsync(new Uri("http://api.decibel.net/v1/Tracks/?trackTitle=" + trackTitle + 
        "&format=json"));
}
 
private void client_TrackSearchCompleted(object sender, DownloadStringCompletedEventArgs e)
{
    if (e.Error == null)
    {
        // Store the query result
        TrackQueryResult queryResult = new JavaScriptSerializer().Deserialize<TrackQueryResult>(e.Result);
 
        // Display the results in a grid
        dtgResults.ItemsSource = queryResult.ResultSet;
    }
    else
    {
        MessageBox.Show("The Decibel Web Service request was not successful due to the following error:" + 
            Environment.NewLine + e.Error.ToString());
    }
}

Tracks: Retrieve track with participations

private void BeginTrackRetrieve(string trackID, string applicationID, string applicationKey)
{
    // Construct the WebClient and set the request headers
    WebClient client = new WebClient();
    client.Encoding = Encoding.UTF8;
    client.Headers.Add("DecibelAppID", applicationID);
    client.Headers.Add("DecibelAppKey", applicationKey);
    client.Headers.Add("DecibelTimestamp", DateTime.Now.ToString("yyyyMMdd HH:mm:ss", 
        System.Globalization.CultureInfo.InvariantCulture));
 
    // Set the callback function which is invoked when the download of the resource completes
    client.DownloadStringCompleted += client_TrackRetrieveCompleted;
 
    // Issue the request to the Decibel Web Service
    string depth = "Names;Participations;ExternalIdentifiers;Genres;Performances";
    client.DownloadStringAsync(new Uri("http://api.decibel.net/v1/Tracks/" + "?depth=" + depth + 
        "&id=" + trackID + "&format=json"));       
}
 
private void client_TrackRetrieveCompleted(object sender, DownloadStringCompletedEventArgs e)
{
    if (e.Error == null)
    {
        // Deserialize the response
        TrackQueryResult queryResult = new JavaScriptSerializer().Deserialize<TrackQueryResult>(e.Result);
 
        // Display the track information
        Track track = queryResult.ResultSet[0];
        txtName.Text = track.Name;
        txtArtists.Text = track.Artists;
        txtTrackNumber.Text = track.TrackNumber;
        txtSequenceNumber.Text = track.SequenceNo.ToString();
        txtDiscNumber.Text = track.DiscNumber.ToString();
        txtSide.Text = track.Side;
        txtTotalSeconds.Text = Util.FormatTime(Convert.ToInt32(track.TotalSeconds));
        chkIsBonus.IsChecked = track.IsBonus;
        chkIsHomemade.IsChecked = track.IsHomemade;
        chkIsBootleg.IsChecked = track.IsBootleg;
        chkIsLive.IsChecked = track.IsLive;
 
        // Add the track participants to the ListBox
        if (track.Participations != null && track.Participations.Length > 0)
        {
            foreach (Participation participation in track.Participations)
                lstParticipants.Items.Add(participation.Participant.Name + " - " + participation.Name);
        }
    }
    else
    {
        MessageBox.Show("The Decibel Web Service request was not successful due to the following error:" + 
            Environment.NewLine + e.Error.ToString());
    }
}

Download XAML

Works: Search for works by name

private void BeginWorkSearch(string workName, string applicationID, string applicationKey)
{
    // Construct the WebClient and set the request headers
    WebClient client = new WebClient();
    client.Encoding = Encoding.UTF8;
    client.Headers.Add("DecibelAppID", applicationID);
    client.Headers.Add("DecibelAppKey", applicationKey);
    client.Headers.Add("DecibelTimestamp", DateTime.Now.ToString("yyyyMMdd HH:mm:ss", 
        System.Globalization.CultureInfo.InvariantCulture));
 
    // Set the callback function which is invoked when the download of the resource completes
    client.DownloadStringCompleted += client_WorkSearchCompleted;
 
    // Issue the request to the Decibel Web Service
    client.DownloadStringAsync(new Uri("http://api.decibel.net/v1/Works/?name=" + workName + "&format=json"));       
}
 
private void client_WorkSearchCompleted(object sender, DownloadStringCompletedEventArgs e)
{
    if (e.Error == null) 
    {
        // Deserialize the response
        WorkQueryResult queryResult = new JavaScriptSerializer().Deserialize<WorkQueryResult>(e.Result);
 
        // Display the results in a grid
        dtgResults.ItemsSource = queryResult.ResultSet;
    }
    else
    {
        MessageBox.Show("The Decibel Web Service request was not successful due to the following error:" + 
            Environment.NewLine + e.Error.ToString());
    }
}

Works: Retrieve work with track appearances

private void BeginWorkRetrieve(string workID, string applicationID, string applicationKey)
{
    // Construct the WebClient and set the request headers
    WebClient client = new WebClient();
    client.Encoding = Encoding.UTF8;
    client.Headers.Add("DecibelAppID", applicationID);
    client.Headers.Add("DecibelAppKey", applicationKey);
    client.Headers.Add("DecibelTimestamp", DateTime.Now.ToString("yyyyMMdd HH:mm:ss", 
        System.Globalization.CultureInfo.InvariantCulture));
 
    // Set the callback function which is invoked when the download of the resource completes
    client.DownloadStringCompleted += client_WorkRetrieveCompleted;
 
    // Issue the request to the Decibel Web Service
    string depth = "Annotations;ChartsAwards;Genres;Movements;Names;Nationalities;Publications;Publishers";
    client.DownloadStringAsync(new Uri("http://api.decibel.net/v1/Works/" + "?depth=" + depth + 
        "&id=" + workID + "&format=json"));       
}
 
private void client_WorkRetrieveCompleted(object sender, DownloadStringCompletedEventArgs e)
{
    if (e.Error == null) 
    {
        // Deserialize the response
        WorkQueryResult queryResult = new JavaScriptSerializer().Deserialize<WorkQueryResult>(e.Result);
        
        // Display the work information
        Work work = queryResult.ResultSet[0];
        txtName.Text = work.Name;
        txtCatalogue.Text = work.Catalogue;               
        txtComposers.Text = work.Composers;
        txtCompositionDate.Text = work.CompositionDate.Name;
        if (work.Genres != null)
        {
            foreach (GenreValue genreValue in work.Genres)
            {
                if (genreValue.Genre != null)
                    txtGenres.Text += genreValue.Genre.Name + ", ";
            }
        }
        if (work.Keys != null)
        {
            foreach (KeyValue keyValue in work.Keys)
            {
                if (keyValue.MusicKey != null)
                    txtKeys.Text += keyValue.MusicKey.Name + ",";
            }
        }
    }
    else
    {
        MessageBox.Show("The Decibel Web Service request was not successful due to the following error:" + 
            Environment.NewLine + e.Error.ToString());
    }
}
 
private void BeginWorkTrackAppearances(string workID, string applicationID, string applicationKey)
{
    // Construct the WebClient and set the request headers
    WebClient client = new WebClient();
    client.Encoding = Encoding.UTF8;
    client.Headers.Add("DecibelAppID", applicationID);
    client.Headers.Add("DecibelAppKey", applicationKey);
    client.Headers.Add("DecibelTimestamp", DateTime.Now.ToString("yyyyMMdd HH:mm:ss", 
        System.Globalization.CultureInfo.InvariantCulture));
 
    // Set the callback function which is invoked when the download of the resource completes
    client.DownloadStringCompleted += client_WorkTrackAppearancesCompleted;
 
    // Issue the request to the Decibel Web Service           
    string depth = "Names;GroupMembers;Nationalities;GeographicAreas;Annotations;ChartsAwards;Relationships;";
    client.DownloadStringAsync(new Uri("http://api.decibel.net/v1/Works/" + workID + "/Tracks" + 
        "?depth=" + depth + "&format=json"));       
}
 
private void client_WorkTrackAppearancesCompleted(object sender, DownloadStringCompletedEventArgs e)
{
    if (e.Error == null)
    {
        // Deserialize the response
        WorkTrackAppearanceQueryResult queryResult 
            = new JavaScriptSerializer().Deserialize<WorkTrackAppearanceQueryResult>(e.Result);
        TrackAppearance[] trackAppearances = queryResult.ResultSet;
        
        // Initialize the data table
        DataTable dataTable = new DataTable();
        dataTable.Columns.Add("Index", typeof(int));
        dataTable.Columns.Add("TrackName", typeof(string));
        dataTable.Columns.Add("ArtistName", typeof(string));
        dataTable.Columns.Add("AlbumName", typeof(string));
        dataTable.Columns.Add("TrackNumber", typeof(string));
        dataTable.Columns.Add("TrackLength", typeof(string));
        int index = 1;
        foreach (TrackAppearance work in queryResult.ResultSet)
        {
            DataRow dataRow = dataTable.NewRow();
            dataRow["Index"] = index;
            dataRow["TrackName"] = work.TrackName;
            dataRow["ArtistName"] = work.TrackArtistName;
            dataRow["AlbumName"] = work.AlbumName;
            dataRow["TrackNumber"] = work.TrackNumber;
            dataRow["TrackLength"] = Util.FormatTime(Convert.ToInt32(work.TotalSeconds));
            dataTable.Rows.Add(dataRow);
            index++;
        }
 
        // Display the track appearances in a grid
        dtgTrackAppearances.IsReadOnly = true;
        dtgTrackAppearances.ItemsSource = dataTable.AsDataView();
    }
    else
    {
        MessageBox.Show("The Decibel Web Service request was not successful due to the following error:" + 
            Environment.NewLine + e.Error.ToString());
    }
}

Download XAML