Статьи

Состояние потребления и сохранение OData в Windows Phone

В этой статье я расскажу о потреблении и сохранении состояния OData в Windows Phone. О OData можно прочитать здесь . Я буду использовать сервис Northwind, предоставляемый OData

Давайте напишем код:

Шаг 1.  Создайте новый проект приложения для Windows Phone. Выберите Silverlight для установленных шаблонов Windows Phone.

Шаг 2: Добавьте сервисную ссылку Nothwind.svc и назовите ее Northwind

http://services.odata.org/Northwind/Northwind.svc/

Шаг 3: Поместите ListBox на панель содержимого Grid в MainPage.Xaml

<ListBox x:Name="MainListBox" Margin="0,0,-12,0" ItemsSource="{Binding}">
   <ListBox.ItemTemplate>
      <DataTemplate>
         <StackPanel Margin="0,0,0,17" Width="432">
            <TextBlock Text="{Binding Path=CompanyName}" TextWrapping="NoWrap" Style="{StaticResource PhoneTextExtraLargeStyle}"/>
            <TextBlock Text="{Binding Path=ContactName}" TextWrapping="NoWrap" Margin="12,-6,12,0" Style="{StaticResource PhoneTextSubtleStyle}"/>
            <TextBlock Text="{Binding Path=Phone}" TextWrapping="NoWrap" Margin="12,-6,12,0" Style="{StaticResource PhoneTextSubtleStyle}"/>
         </StackPanel>
      </DataTemplate>
   </ListBox.ItemTemplate>
</ListBox>

Шаг 4: Добавьте ниже, используя директиву в MainPage.Xaml.cs. Второе использование директива это пространство имен проекта и имя ссылки на сервис.

using System.Data.Services.Client;
using WP_Consuming_OData.Northwind;

 Шаг 5: Определите ниже переменных уровня класса.

public partial class MainPage : PhoneApplicationPage
{
   private NorthwindEntities context;
   private readonly Uri northwindUri =
   new Uri(http://services.odata.org/Northwind/Northwind.svc/);
   private DataServiceCollection<Customer> customers;
   private bool isDataLoaded;

 Шаг 6: Добавьте метод ниже в MainPage.Xaml.cs, который будет вызываться при восстановлении приложения. Переменная isDataLoaded для проверки того, что данные уже находятся в памяти, если данные не находятся в памяти, будет проверен словарь состояний для загрузки, если данные не присутствуют в словаре состояний, также будет вызвана служба OData.

protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
   // Get the object data if it is not still loaded.
   if (!this.isDataLoaded)
   {
      object storedState;
      DataServiceState state;
      if (this.State.TryGetValue("DataServiceState", out storedState))
      { 
         // Deserialize the DataServiceState object.
         state = DataServiceState.Deserialize(storedState as string);
         var restoredContext = (NorthwindEntities)state.Context;

         // Set the binding collections from the stored collection.
         var restoredCustomers = state.RootCollections["Customers"] as DataServiceCollection<Customer>;
      this.LoadData(restoredContext, restoredCustomers);
      }
      else
      {
         this.LoadData();
      }
   }
}

Шаг 7: Добавьте нижеприведенный метод в MainPage.Xaml.cs, который будет сериализовать и хранить состояние передачи данных.

protected override void OnNavigatingFrom(System.Windows.Navigation.NavigatingCancelEventArgs e)
{
   var collections = new Dictionary<string, object>();
   collections.Add("Customers", customers);
   this.State["DataServiceState"] = DataServiceState.Serialize(context, collections);
}

Step 8: Now add below LoadData method in MainPage.Xaml.cs which will be invoked when stored data context is used to bind.

public void LoadData(NorthwindEntities context, DataServiceCollection<Customer> customers)
{
   this.context = context;
   this.customers = customers;
   this.isDataLoaded = true;
}

Шаг 9: Метод LoadData в MainPage.Xaml.cs будет вызван для загрузки данных из сервиса в первый раз, и если контекст не сохранен в состоянии страницы.

private void LoadData()
{
   context = new NorthwindEntities(northwindUri);
   customers = new DataServiceCollection<Customer>(context);
   var query = from cust in context.Customers select cust;
   customers.LoadCompleted += new EventHandler<LoadCompletedEventArgs>(customers_LoadCompleted);
   // Load the Customers feed by executing the LINQ query.
   customers.LoadAsync(context.Customers);
}

Шаг 10: Добавьте ниже метона в MainPage.Xaml.cs, который происходит, когда загрузка данных завершена.

void customers_LoadCompleted(object sender, LoadCompletedEventArgs e)
{
   if (e.Error == null)
   {
      if (customers.Continuation != null)
      {
         customers.LoadNextPartialSetAsync();
      }
      else
      {
         this.LayoutRoot.DataContext = customers;
         this.isDataLoaded = true;
      }
   }
   else
   {
      MessageBox.Show(string.Format("An error has occurred: {0}", e.Error.Message));
   }
}

Шаг 11: Теперь запустите приложение и дождитесь загрузки данных и привязки к списку, а затем нажмите кнопку Пуск.

Вы получите исключение Northwind.NorthwindEntities не может быть сериализовано, как показано ниже.

Теперь откройте файл Reference.cs, доступный по указанному ниже пути.

Добавьте ниже, используя директиву в Reference.cs

using System.Runtime.Serialization

Now add [DataContract] attribute to NorthwindEntities class

[DataContract]
public partial class NorthwindEntities : global::System.Data.Services.Client.DataServiceContext
{

Шаг 12. Теперь запустите приложение и дождитесь загрузки данных и привязки к списку, а затем нажмите кнопку «Пуск». На этот раз не будет никаких исключений.

На этом заканчивается статья о потреблении и сохранении состояния OData в Windows Phone.