В последний день 2011 года я сделал DynamicBackgroundBehavior — довольно странное поведение, которое играет вспомогательную роль в моем последнем приложении для Windows Phone « Что готовит ». Он в основном показывает изображение из строки поиска в качестве фона, используя поиск изображений Bing. Довольно аккуратно. Пока Microsoft не решила немного изменить API поиска Bing. До этого это была бесплатная неограниченная поездка — примерно с августа вам придется купить пакет поисков (все, что меньше 5000 поисков в месяц, бесплатно). И некоторые другие вещи были изменены.
Microsoft предоставляет небольшую клиентскую библиотеку C #, которая должна решить все это с использованием протокола OData. Печально то, что за всю жизнь я не смог заставить его скомпилировать на Windows Phone. Поэтому я закончил анализировать образец PHP (* shudder *) в этом документе — документ Word не меньше — чтобы увидеть, что мне нужно было сделать (см. Стр. 27 и далее).
С точки зрения кодирования были изменены следующие детали:
- Фактическое местоположение API было изменено с http://api.bing.net/xml.aspx на https://api.datamarket.azure.com/Data.ashx/Bing/Search/v1/Image
- Схема элемента MediaUrl, куда возвращается реальное изображение, перемещена из пространства имен http://schemas.microsoft.com/LiveSearch/2008/04/XML/multimedia в пространство имен http://schemas.microsoft.com/ado / 2007/08 / DataServices
- Он использует ключ учетной записи вместо идентификатора приложения.
- Идентификатор приложения должен отправлять base 64, закодированный в заголовке запроса, вместо URL в виде простого текста.
Ладно. Мой сыр немного сдвинулся. Обо всем по порядку. Мне нужен кодированный base64 текст. Образцы этого в Интернете десять центов, я взял этот:
/// <summary> /// Converts string to base64 /// </summary> /// <param name="data"></param> /// <returns></returns> private string Base64Encode(string data) { try { var encData_byte = new byte[data.Length]; encData_byte = System.Text.Encoding.UTF8.GetBytes(data); return Convert.ToBase64String(encData_byte); } catch (Exception e) { throw new Exception("Error in Base64Encode" + e.Message); } }
Теперь метод, который выполняет фактический вызов API поиска Bing, немного изменился, но не сильно:
/// <summary> /// Start the image request using Bing Serach /// </summary> /// <param name="searchString"></param> protected void StartGetFirstImage(string searchString) { if (!string.IsNullOrWhiteSpace(searchString)) { var queryUri = string.Format( "https://api.datamarket.azure.com/Data.ashx/Bing/Search/v1/Image?Query=%27{0}%27&$top=1&$format=Atom", HttpUtility.UrlEncode(searchString)); var request = WebRequest.Create(queryUri) as HttpWebRequest; request.Headers["Authorization"] = "Basic " + Base64Encode(string.Format("{0}:{0}", BingSearchKey)); var response = Observable.FromAsyncPattern<WebResponse>( request.BeginGetResponse, request.EndGetResponse)(); response.Subscribe(WebClientOpenReadCompleted, WebClientOpenReadError); } }
Обратите внимание на новый URL. Он идет в другое место, поисковый термин должен быть заключен в% 27 (то есть в двойную кавычку), и мне нужно указать формат (Atom). Действительно интересная вещь, которую я пометил красным, по разным причинам:
- Коллекция Response.Headers в Windows Phone не поддерживает метод Add. Это немного остановило меня, пока я не понял, что вы можете напрямую вставить новый ключ в коллекцию, используя [«Авторизация»] =.
- Теперь аутентификация обычная, за ней следуют пробел, ключ вашей учетной записи, двоеточие, снова ваш ключ и этот ключ: последовательность ключей должна быть закодирована с помощью кода 64. Почему это реализовано таким образом — понятия не имею, но оно получает ваш ключ — и проверяется.
И последнее, что в обратном вызове WebClientOpenReadCompleted мне нужно использовать, мне нужно использовать « http://schemas.microsoft.com/ado/2007/08/dataservices » для пространства имен, как я уже говорил.
И тогда мое маленькое поведение Windows Phone снова работает. Фиксированную версию можно скачать здесь . Я исправлю свою библиотеку # wp7nl в кодплексе как можно скорее.