Picture Search is a Windows Store sample app that is used to search pictures with Bing Search. The first part of this article series showed the implementation of a ASP.NET Web API service that itself called the Bing service. The second part of this series is about creating a Windows Runtime component that makes a request to the Web API service. The article is not only about the invocation of the service, but also the implementation of a Windows Runtime Component.
Deutschsprachige Version des Artikels
Picture Search in the App Store
Libraries for Windows Store Apps
For creating libraries for Windows Store apps using C# and XAML different options are available:
- Class Library (Windows Store Apps)
- Windows Runtime Component
- Portable Class Library
The Class Library (Windows Store Apps) is a .NET library as we know it from creating .NET applications. However, here the library is reduced to a .NET subset with classes and methods that are available for Windows Store apps.
With the Add New Project template, The Portable Class Library cannot be found in the category of Windows Store templates. Instead, this template is available in the Windows category. This library is not restricted to use from Windows Store apps, you can use it with Windows desktop apps or Silverlight apps instead. The library can be configured for the available set of technologies (including Xbox 360) to create applications. Accordingly to the configuration only a subset of .NET is available.
The third option is the Windows Runtime Component. Creating such a library, the library can not only be used with .NET applications, but also with other Windows Store app technologies such as JavaScript and C++. However, creating this library with C# and using it from C++ or JavaScript also means that the .NET runtime needs to be loaded
Creating a Windows Runtime Component
Windows Runtime Components can be created with a Visual Studio project template.
Only Sealed Types
An important restriction for this type of library is that all public types must be sealed – with the exception of UI components.
PictureInformation represents the data which is received from the service: Title, Url, ThumbnailUrl, and Source. This class is similar to other .NET classes – with the exception that it needs to be sealed. Properties can be offered by Windows Runtime components directly.
public sealed class PictureInformation { public string Title { get; set; } public string Url { get; set; } public string ThumbnailUrl { get; set; } public string Source { get; set; } }
Converting a JSON Array to an Object List
SearchManager is the second class in this assembly. This class is sealed as well.
The GetImagesAsyncInternal method makes a call to the Web service. Similar to the first part of this article series, the HttpClient class is used to make the request. GetStringAsync returns a JSON result from the service.
A JSON string can be parsed by using classes from the namespace Windows.Data.Json. The Windows Runtime offers JSON and XML classes in the namespaces Windows.Data.Json, Windows.Data.Xml.Dom, and Windows.Data.Xml.Xsl.
private async Task<IEnumerable<PictureInformation>> GetImagesAsyncInternal(string searchTerm) { string urlRequest = url + searchTerm; var client = new HttpClient(); string jsonResult = await client.GetStringAsync(urlRequest); var results = await Task.Run<IEnumerable<PictureInformation>>(() => { var searchItems = new List<PictureInformation>(); JsonArray result; if (JsonArray.TryParse(jsonResult, out result)) { foreach (var jsonItem in result) { JsonObject jsonObj = jsonItem.GetObject(); var searchItem = new PictureInformation { Title = jsonObj["Title"].GetString(), Url = jsonObj["Url"].GetString(), Source = jsonObj["Source"].GetString(), ThumbnailUrl = jsonObj["ThumbnailUrl"].GetString() }; searchItems.Add(searchItem); } } return searchItems; }); return results; }
The GetImagesAsyncInternal method uses the C# 5 async and await keywords for calling asynchronous methods. As usual with .NET async code, the method returns a task. The caller of an async mehtod does not block the caller thread. Continuation tasks are used behind the scenes with the await keyword.
If this method would be declared public, a compile run results in the error that the task of the type is not a valid Windows runtime type. Public methods within Windows runtime components can only use Windows runtime compatible types in the signature.
A Task can be converted to a Windows runtime type by using the extension method AsAsyncOperation. AsAsyncOperation is an extension method for the Task type and returns IAsyncOperation. IAsyncOperation is the interface of the Windows runtime (namespace Windows.Foundation) for asynchronous calls, and can be used with C# 5 async and await.
public IAsyncOperation<IEnumerable<PictureInformation>> GetImagesAsync(string searchTerm) { Task<IEnumerable<PictureInformation>> t = GetImagesAsyncInternal(searchTerm); return t.AsAsyncOperation(); }
Summary
Windows Runtime components are libraries for Windows Store apps and can be used with .NET, JavaScript, and C++. Contrary to other .NET libraries, this library is restricted on using Windows runtime types in the signature. With the help of small utilities, such as extension methods, this is an easy task.
Christian
More about Windows Store apps in my book Professional C# 2012 and .NET 4.5, and my Windows Store App workshops.
This article series:
Part 1 – Web API – Search with Bing
Part 2 – Windows Runtime Components
Part 3 – Layout
Part 4 – Settings
Part 5 – Search
Part 6 – Share