Exercise 2: Creating the Windows Phone 7 Application

In this exercise, you will create a Windows Phone 7 application to upload images from the phone to the SharePoint picture 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.Cam.sln file located at %TrainingKitPath%\Labs\UploadingImagestoSharePoint\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.Cam 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.Cam 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 Maintenance Pictures 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.

Task 4 – Adding a Reference to the SharePoint Imaging.asmx Web Service

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

  1. In the Solution Explorer, in the WP7.AccAdv.Cam project, right click Service References and select Add Service Reference.
  2. In the Addresstextbox enter the URL to the imaging.asmx SharePoint Web service for the site where you created the Maintenance Picture library.
  3. Example: https://fbawp7/_vti_bin/imaging.asmx
  4. Click Go.
  5. Once the service is resolved, enter ImagingService 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.Cam 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. Locate the ImagingSoap binding element.
  5. Add the following attribute to the ImagingSoap binding element.

    XML

    enableHttpCookieContainer="true"

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

    Figure 3

    Adding the enableHttpCookieContainer attribute

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

    Figure 4

    Expected exception when modifying a service with the enableHttpCookieContainer attribute 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 6 – Retrieving Maintenance Images from SharePoint

In this task, you will use the SharePoint imaging.asmx Web service to return maintenance images from the SharePoint list.

Note:
Note: This lab uses the Imaging Web service. This service only works with Picture libraries, it does not work with Asset Libraries.

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

    C#

    public void LoadPictures() { ImagingService.ImagingSoapClient imgSvc = new ImagingService.ImagingSoapClient(); imgSvc.CookieContainer = App.CookieJar; imgSvc.GetListItemsCompleted += new EventHandler<ImagingService.GetListItemsCompletedEventArgs> (imgSvc_GetListItemsCompleted); imgSvc.GetListItemsAsync(Constants.LIST_TITLE, ""); }

    The above code uses the proxy class Visual Studio 2010 generated for the imaging.asmx service to query the Maintenance Pictures SharePoint library.

  3. Add the following code under the //TODO: 5.2.2 comment to define the imgSvc_GetListItemsCompleted method:

    C#

    void imgSvc_GetListItemsCompleted(object sender, ImagingService.GetListItemsCompletedEventArgs e) { IEnumerable<XElement> rows = e.Result.Descendants (XName.Get("row", "#RowsetSchema")); IEnumerable<SPPicture> images = from element in rows select new SPPicture { Title = (string)element.Attribute("ows_Title"), PictureUrl = (string)element. Attribute("ows_EncodedAbsUrl") }; Deployment.Current.Dispatcher.BeginInvoke(() => { if (Pictures == null) { Pictures = new ObservableCollection<SPPicture>(); } Pictures.Clear(); images.ToList().ForEach(a => Pictures.Add(a)); }); }

    The imgSvc_GetListItemsCompleted method fires when the call to the GetListItemsAsyncmethod completes. The method parses the result set, creates an instance of the SPPicture class that represents each picture in the SharePoint library, and adds the SPPicture instances to the Pictures observable collection. The Pictures observable collection is bound to the MainPage user control in the Windows Phone 7 application. The MainPage user control displays the maintenance pictures retrieved from the SharePoint library.

  4. Save MainViewModel.cs.

Task 7 – Uploading an Image to a SharePoint Picture Library

In this task, you will use the SharePoint imaging.asmx Web service to upload an image to the maintenance picture library created in Exercise 1.

Note:
Note: This lab uses the Imaging Web service. This service only works with Picture libraries, it does not work with Asset Libraries.

  1. In the WP7.AccAdv.Cam project, in the ViewModels folder, open the PictureUploadViewModel.cs file.
  2. Add the following code under the //TODO: 5.2.3 comment to define the SaveToLibary method:

    C#

    public void SaveToLibary(Action callback) { ImagingService.ImagingSoapClient imgSvc = new ImagingService.ImagingSoapClient(); imgSvc.CookieContainer = App.CookieJar; imgSvc.UploadCompleted += new EventHandler<ImagingService.UploadCompletedEventArgs> (imgSvc_UploadCompleted); imgSvc.UploadAsync(Constants.LIST_TITLE, "", this.DataModel.PictureBytes, this.DataModel.FileName, true, callback); }

    The above code uses the proxy class Visual Studio 2010 generated for the imaging.asmx to upload the image. The image is uploaded as a byte array. The UploadAsync method passes a callback method as the last parameter. The callback method executes later at the end of the chain of method calls. The callback will navigate the application back to the main page after the chain of method calls complete.

  3. Add the following code under the //TODO: 5.2.4 comment to define the imgSvc_UploadCompleted method:

    C#

    void imgSvc_UploadCompleted(object sender, ImagingService.UploadCompletedEventArgs e) { GetNewItemMetaData(this.dataModel.FileName, (Action)e.UserState); }

    The imgSvc_UploadCompleted method executes after the picture upload completes. The imgSvc_UploadCompleted method’s UploadCompletedEventArgs parameter includes a return value consisting of an XML string with the last modified date and time for the uploaded file. It does not return a URL or ID of the newly uploaded file.

  4. Save PictureUploadViewModel.cs

Task 8 – Retrieving the Newly Uploaded File ID

In this task, you will use the SharePoint imaging.asmx Web service to retrieve the ID of the file uploaded in Task 7.

  1. In the WP7.AccAdv.Cam project, in the ViewModels folder, open the PictureUploadViewModel.cs file.
  2. Add the following code under the //TODO: 5.2.5 comment to define the GetNewItemMetaData method:

    C#

    public void GetNewItemMetaData(string fileName, Action callback) { string[] fileNameList = new string[1]; fileNameList[0] = fileName; ImagingService.ImagingSoapClient imgSvc = new ImagingService.ImagingSoapClient(); imgSvc.CookieContainer = App.CookieJar; ArrayOfString fileNameArray = new ArrayOfString(); fileNameArray.Add(fileName); imgSvc.GetItemsXMLDataCompleted += new EventHandler<ImagingService.GetItemsXMLDataCompletedEventArgs> (imgSvc_GetItemsXMLDataCompleted); imgSvc.GetItemsXMLDataAsync(Constants.LIST_TITLE, "", fileNameArray, callback); }

    The above code uses the proxy class Visual Studio 2010 generated for the imaging.asmx to retrieve a list of files from the picture library.

  3. Add the following code under the //TODO: 5.2.6 comment to define the imgSvc_GetItemsXMLDataCompleted method

    C#

    void imgSvc_GetItemsXMLDataCompleted(object sender, ImagingService.GetItemsXMLDataCompletedEventArgs e) { string ns = "https://schemas.microsoft.com/sharepoint/soap/ois/"; IEnumerable<XElement> items = e.Result.Descendants(XName.Get("item", ns)); var i = from element in items select (string)element.Attribute("ID"); UpdateImageById(Constants.LIST_TITLE, i.First(), (Action)e.UserState); }

    The imgSvc_GetItemsXMLDataCompleted method executes after the GetItemsXMLDataAsync method returns. This method uses LINQ to parse the results for the ID attribute of the picture uploaded in Task 7. This method calls the UpdateImageById method and passes in the ID attribute.

  4. SavePictureUploadViewModel.cs

Task 9 – Updating the Picture Metadata

In this task, you will use the SharePoint lists.asmx Web service to update picture metadata.

  1. In the WP7.AccAdv.Cam project, in the ViewModels folder, open the PictureUploadViewModel.cs file.
  2. Add the following code under the //TODO: 5.2.7 comment to define the UpdateImageByIdmethod:

    C#

    void UpdateImageById(string listName, string id, Action callback) { XElement batch = new XElement("Batch", new XAttribute("OnError", "Continue"), new XAttribute("ListVersion", "1"), new XAttribute("ViewName", ""), new XElement("Method", new XAttribute("ID", "1"), new XAttribute("Cmd", "Update"), new XElement("Field", id, new XAttribute("Name", "ID")), new XElement("Field", this.dataModel.Title, new XAttribute("Name", "Title")) )); ListsSoapClient lists = new ListsSoapClient(); lists.CookieContainer = App.CookieJar; lists.UpdateListItemsCompleted += new EventHandler<UpdateListItemsCompletedEventArgs> (lists_UpdateListItemsCompleted); lists.UpdateListItemsAsync(listName, batch, callback); }

    The above code uses the proxy class Visual Studio 2010 generated for the lists.asmx Web service to update the picture metadata. The UpdateListItemsAsync method accepts a string of XML that contains one or more batch operations.

  3. Add the following code under the //TODO: 5.2.8 comment to define the lists_UpdateListItemsCompleted method:

    C#

    void lists_UpdateListItemsCompleted(object sender, UpdateListItemsCompletedEventArgs e) { Deployment.Current.Dispatcher.BeginInvoke(() => { ((Action)e.UserState).DynamicInvoke(); }); }

    The lists_UpdateListItemsCompleted method executes after the UpdateListItemsAsync method completes. At this point, the picture is successfully uploaded and its metadata is set. The lists_UpdateListItemsCompleted method executes the callback that has travelled along the chain of asynchronous calls. The callback is a pointer to code that navigates the application to the main page.

  4. Save PictureUploadViewModel.cs