Exercise 2: Creating the Windows Phone 7 Application

In this exercise, you will create a Windows Phone 7 application to read and display images from the vehicle images SharePoint library created in exercise 1.

Task 1 – Beginning the Exercise

In this task, you will open the lab solution in Visual Studio 2010.

  1. Make sure that you have downloaded and installed the items listed in System Requirements above prior to beginning this exercise.
  2. Launch Visual Studio 2010 as administrator and open the lab project by selecting File » Open » Project.
    1. Browse to the WP7.AccAdv.Images.sln file located at %TrainingKitPath%\Labs\IntegratingSharePointImages\Source\Before and select it.
    2. Click Open to open the solution.

Task 2 – Configuring Constants in the Windows Phone 7 Application

In this task, you will configure the constants used in the Windows Phone 7 application to work with your development environment.

  1. In the WP7.AccAdv.Images project, in the Utilities folder, open the Constants.cs file.
  2. Change the value for the USER_NAME and USER_PASSWORD constants to represent a Forms Based Authentication user specific to your development environment. For this lab, the user requires read and write permissions.
  3. Change the value for the AUTHENTICATION_SERVICE_URL constant to the URL specific to your development environment.
  4. The following code example demonstrates the value for a SharePoint server named fbawp7.

    C#

    public const string AUTHENTICATION_SERVICE_URL = "https://fbawp7/_vti_bin/authentication.asmx";

Task 3 – Adding a Reference to the SharePoint Lists.asmx Web Service

In this task, you will add a reference to the SharePoint lists.asmx Web service.

  1. In the Solution Explorer, in the WP7.AccAdv.Images project, right click Service References and select Add Service Reference.
  2. In the Addresstextbox enter the URL to the lists.asmx SharePoint web service for the site where you created the Vehicle Images library.
  3. Example: https://fbawp7/_vti_bin/lists.asmx
  4. Click Go.
  5. Once the service is resolved, enter ListService in the Namespace textbox.
  6. Click OK.

In this task, you will modify the ServiceReferences.ClientConfig file to support the CookieContainer used with Forms BasedAuthentication. The code used to authenticate to the SharePoint server in this lab uses Forms Based Authentication. Forms Based Authentication requires the use of a CookieContainer. Please see the Security With SharePoint And Windows Phone 7 Applications Module for more information about Forms Based Authentication.

  1. In the WP7.AccAdv.Images project, open the ServiceReferences.ClientConfig file.
  2. Locate the ListsSoap binding element.
  3. Add the following attribute to the ListsSoap binding element.

    XML

    enableHttpCookieContainer="true"

  4. The following screenshot shows what the ListSoap binding element looks like after the above code is added.

    Figure 4

    Adding the emableHTttpCookieContainer attribute

    Note:
    The following exception will occur if you do not make this change to the ServiceReferences.ClientConfig file.

    Figure 5

    Expected exception when modifying a service with the enabledHttpCookieContainer defined

    Note:
    If you change the interface to one or both of the services the application calls and need to update the service reference you will need to remove the XML code above from the ServiceReferences.ClientConfig file then update the service reference. After the service reference update is complete, add the XML code back to the ServiceReferences.ClientConfig file.

Task 5 – Retrieving Vehicle Images from SharePoint

In this task, you will use the SharePoint lists.asmx Web service to return vehicle images from the SharePoint library.

  1. In the WP7.AccAdv.Images project, in the ViewModels folder, open the MainViewModel.cs file.
  2. Add the following code under the //TODO: 5.1.1 comment to define the LoadImages method:

    C#

    public void LoadImages() { XElement viewFields = new XElement("ViewFields", new XElement("FieldRef", new XAttribute("Name", "Title")), new XElement("FieldRef", new XAttribute("Name", "_Comments")), new XElement("FieldRef", new XAttribute("Name", "ThumbnailOnForm"))); ListsSoapClient lists = new ListsSoapClient(); lists.CookieContainer = App.CookieJar; lists.GetListItemsCompleted += new EventHandler<GetListItemsCompletedEventArgs> (lists_GetListItemsCompleted); lists.GetListItemsAsync("Vehicle Images", string.Empty, null, viewFields, null, null, null); }

    The above code uses the proxy class Visual Studio 2010 generated for the lists.asmx service to query the Vehicle Images SharePoint library.

  3. Add the following code under the //TODO: 5.1.2 comment to define the lists_GetListItemsCompleted method:

    C#

    void lists_GetListItemsCompleted(object sender, GetListItemsCompletedEventArgs e) { IEnumerable<XElement> rows = e.Result.Descendants(XName.Get ("row", "#RowsetSchema")); IEnumerable<SPImage> images = from element in rows select new SPImage() { Title = (string)element.Attribute("ows_Title"), Comments = Utils.HtmlToText((string) element.Attribute("ows__Comments")), ImgUrl = (string)element.Attribute ("ows_ThumbnailOnForm") }; Deployment.Current.Dispatcher.BeginInvoke(() => { if (Images == null) { Images = new ObservableCollection<SPImage>(); } Images.Clear(); images.ToList().ForEach(a => Images.Add(a)); }); }

    The lists_GetListItemsCompleted method fires when the call to the lists.asmx SharePoint Web service completes. The method parses the result set, creates an instance of the SPImage class that represents each image in the SharePoint library, and adds the SPImage instances to the Images observable collection. The Images observable collection is bound to the MainPage user control in the Windows Phone 7 application. The MainPage user control displays the vehicle images retrieved from the SharePoint library.

  4. Save MainViewModel.cs.

Task 6 – Binding Image URL to an Image Object Using a Custom Converter

In this task, you will use a custom converter object to retrieve an image from a URL and bind to an Image object in the MainPage user control.

  1. In the WP7.AccAdv.Images project, in the Utilities folder, open the Utils.cs file.
  2. Add the following code under the //TODO: 5.1.3 comment to define the Convert method:

    C#

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { BitmapImage bmp=new BitmapImage(); System.Net.HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(value.ToString()); request.CookieContainer = App.CookieJar; request.Method = "GET"; request.BeginGetResponse((s) => { HttpWebRequest requestResult = (HttpWebRequest)s.AsyncState; HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(s); Stream content = response.GetResponseStream(); System.Windows.Deployment.Current.Dispatcher.BeginInvoke(() => { bmp.SetSource(content); }); }, request); return bmp; }

    The ImageConverter class’s Convert method is used in the MainPage user control to retrieve the image binary using the image url. The Convert method binds the image stream to a BitmapImage object. Image controls contained in the MainPage user control pass the Image URL to the converter and bind to the BitmapImage object returned by the Convert method.

  3. Save the Utils.cs.
  4. In the WP7.AccAdv.Images project, open the MainPage.xaml file.
  5. Replace the <!-- TODO: 5.1.4 --> comment with the following namespace markup:

    Xaml

    xmlns:local="clr-namespace:WP7.AccAdv.Images;assembly=WP7.AccAdv.Images"
    Note:
    You must replace the TODO comment. The project will not run correctly if the TODO comment is not removed.

    The namespace markup associates a prefix (local) with a namespace (WP7.AccAdv.Images) from an assembly. The compiler uses the namespace to identify a resource or class.

  6. Add the following markup under the <!-- TODO: 5.1.5 --> comment to define the ImageConverter as a resource :

    Xaml

    <phone:PhoneApplicationPage.Resources> <local:ImageConverter x:Key="ImageConverter" /> </phone:PhoneApplicationPage.Resources>

    The PhoneApplicationPage.Resouces markup creates a resource library scoped at the page level. This resource library contains an instance of the ImageConverter object. It is be accessed using the ImageConverter key.

  7. Replace the <!-- TODO: 5.1.6 --> comment with the following markup:

    Xaml

    Converter={StaticResource ImageConverter}

    Example: <Image Height="470" Width="470" Canvas.Left="0" Source="{Binding SelectedImage.ImgUrl,
                     Converter={StaticResource ImageConverter }}" />

    This markup instructs the code to call the ImageConverter class to convert the data bound value. Image objects cannot use a URL as a source. The ImageConverter object is used to convert the URL reference to a BitmapImage object which can be used as a Source object.

    Note:
    You must replace the TODO comment. The project will not run correctly if the TODO comment is not removed.

  8. Replace the <!-- TODO: 5.1.7 --> comment with the following markup:

    Xaml

    Converter={StaticResource ImageConverter}

    Example: <Image Stretch="UniformToFill" Source="{Binding ImgUrl,
                     Converter={StaticResource ImageConverter }}"  
    FakePre-23bdc582aebc428998b275616d0c1c42-11a17aaf56fa4876af5616bd04ee9f26

    This markup instructs the code to call the ImageConverter class to convert the data bound value. Image objects cannot use a URL as a source. The ImageConverter object is used to convert the URL reference to a BitmapImage object which can be used as a Source object.

    Note:
    You must replace the TODO comment. The project will not run correctly if the TODO comment is not removed.