原文:与众不同 windows phone (29) - Communication(通信)之与 OData 服务通信

[索引页]
[源码下载]

与众不同 windows phone (29) - Communication(通信)之与 OData 服务通信

作者:webabcd

介绍
与众不同 windows phone 7.5 (sdk 7.1) 之通信

  • 与 OData 服务通信

示例
1、服务端(采用 Northwind 示例数据库)
NorthwindService.svc.cs

/** 提供 OData 服务,详细说明请参见 WCF Data Services 的相关文章:http://www.cnblogs.com/webabcd/category/181636.html*/using System;
using System.Collections.Generic;
using System.Data.Services;
using System.Data.Services.Common;
using System.Linq;
using System.ServiceModel.Web;
using System.Web;namespace Web.Communication
{// 出现异常时,返回详细的错误信息[System.ServiceModel.ServiceBehavior(IncludeExceptionDetailInFaults = true)]public class NorthwindService : DataService<NorthwindEntities>{public static void InitializeService(DataServiceConfiguration config){// 全部实体全部权限config.SetEntitySetAccessRule("*", EntitySetRights.All);// 指定服务所支持的 OData 协议的最大版本config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;}}
}

2、客户端(ViewModel 层)
MyViewModel.cs

/** 调用 OData 服务的 ViewModel 层* * DataServiceCollection<T> - OData 服务的实体数据集合,添加、删除和更新数据时都会提供通知,继承自 ObservableCollection<T>*     Count - 实体数据集合中的实体数*     CollectionChangedCallback - 实体集合更改时调用的委托*     EntityChangedCallback - 实体更改时调用的委托*     Continuation - 是否还有下一页数据*     LoadAsync(IQueryable<T> query) - 通过指定的查询异步加载数据*     CancelAsyncLoad() - 取消异步加载请求*     LoadNextPartialSetAsync() - 加载下一页数据*     Detach() - 停止跟踪集合中的全部实体*     LoadCompleted - 异步数据加载完成后触发的事件*     * * DataServiceState - 服务状态*     Serialize(DataServiceContext context, Dictionary<string, Object> collections) - 序列化 DataServiceContext 对象以及页面的相关数据*         注:引用 OData 服务后,会自动生成一个继承自 DataServiceContext 的代理类,如果需要序列化的话,则必须手动为其加上 [System.Runtime.Serialization.DataContract] *     Deserialize() - 反序列化,返回 DataServiceState 类型的数据*     Context - 相关的 DataServiceContext 对象*     RootCollections - 相关的数据* * * 注:* OData 服务的相关查询参数参见:http://msdn.microsoft.com/en-us/library/gg309461.aspx*/using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;using System.ComponentModel;
using Demo.NorthwindContext;
using System.Data.Services.Client;
using System.Linq;
using System.Collections.Generic;namespace Demo.Communication.ODataClient.ViewModel
{public class MyViewModel : INotifyPropertyChanged{// 引用过来的 OData 服务private NorthwindEntities _context;// OData 服务地址private Uri _northwindUri = new Uri("http://localhost:15482/Communication/NorthwindService.svc/");// 相关数据,DataServiceCollection<T> 继承自 ObservableCollection<T>public DataServiceCollection<Category> Categories { get; private set; }public void LoadData(){_context = new NorthwindEntities(_northwindUri);// 实例化 DataServiceCollection<Category>,并注册相关事件Categories = new DataServiceCollection<Category>(_context);Categories.LoadCompleted += new EventHandler<LoadCompletedEventArgs>(Categories_LoadCompleted);// 获取全部 Categories 数据,并且一次请求带上 Categories 的所有 ProductsDataServiceQuery<Category> query = _context.Categories.Expand("Products");Categories.LoadAsync(query);NotifyPropertyChanged("Categories");}void Categories_LoadCompleted(object sender, LoadCompletedEventArgs e){if (e.Error == null){// 如果服务端有分页,则继续获取直至获取完全部数据if (Categories.Continuation != null)Categories.LoadNextPartialSetAsync();}else{Deployment.Current.Dispatcher.BeginInvoke(delegate{MessageBox.Show(e.Error.ToString());});}}// 新增产品数据public void AddProduct(Product product){_context.AddToProducts(product);Categories.Single(p => p.CategoryID == product.CategoryID).Products.Add(product);SaveChanges();}// 删除产品数据public void DeleteProduct(Product product){_context.DeleteObject(product);Categories.Single(p => p.CategoryID == product.CategoryID).Products.Remove(product);SaveChanges();}// 更新产品数据public void UpdateProduct(Product product){_context.UpdateObject(product);SaveChanges();}public void SaveChanges(){// 异步向 OData 服务提交最近的数据变化
            _context.BeginSaveChanges(OnChangesSaved, _context);}private void OnChangesSaved(IAsyncResult result){Deployment.Current.Dispatcher.BeginInvoke(delegate{_context = result.AsyncState as NorthwindEntities;try{// 完成数据提交
                    _context.EndSaveChanges(result);}catch (Exception ex){MessageBox.Show(ex.ToString());}});}// 一个异步获取数据的例子,此 Demo 没用到此方法public void GetData(){// 查找 Products 里 ProductID 为 1 的数据var query = _context.CreateQuery<Product>("Products").AddQueryOption("$filter", "ProductID eq 1");// 异步请求 OData 服务query.BeginExecute(p =>{var myQuery = p.AsyncState as DataServiceQuery<Product>;try{// 获取请求结果var result = myQuery.EndExecute(p).First();// 更新数据
                    _context.UpdateObject(result);// 将更新后的结果提交到 OData 服务
                    SaveChanges();}catch (Exception ex){Deployment.Current.Dispatcher.BeginInvoke(delegate{MessageBox.Show(ex.ToString());});}}, query);}// 序列化当前数据,Deactivated 保存此值到应用程序状态,参见 App.xaml.cspublic string GetState(){var dict = new Dictionary<string, object>();dict["categories"] = Categories;return DataServiceState.Serialize(_context, dict);}// 恢复数据,当从 tombstone 状态进入 Activated 时,则从应用程序状态中恢复数据,参见 App.xaml.cspublic void RestoreState(string appState){Dictionary<string, object> dict;if (!string.IsNullOrEmpty(appState)){DataServiceState state = DataServiceState.Deserialize(appState);// 获取相关数据var context = state.Context as NorthwindEntities;dict = state.RootCollections;DataServiceCollection<Category> categories = dict["Categories"] as DataServiceCollection<Category>;// 恢复相关数据_context = context;Categories = categories;Categories.LoadCompleted += new EventHandler<LoadCompletedEventArgs>(Categories_LoadCompleted);NotifyPropertyChanged("Categories");}}public event PropertyChangedEventHandler PropertyChanged;private void NotifyPropertyChanged(string propertyName){var propertyChanged = PropertyChanged;if (propertyChanged != null)propertyChanged(this, new PropertyChangedEventArgs(propertyName));}}
}

3、客户端(View 层)
App.xaml

<Application x:Class="Demo.App"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"       xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"xmlns:odataViewModel="clr-namespace:Demo.Communication.ODataClient.ViewModel"><Application.Resources><odataViewModel:MyViewModel x:Key="ODataViewModel" /></Application.Resources></Application>

App.xaml.cs

        private void Application_Activated(object sender, ActivatedEventArgs e){// 从 tombstone 状态返回,则恢复相关数据,参见:“调用 OData 服务”if (!e.IsApplicationInstancePreserved){if (PhoneApplicationService.Current.State.ContainsKey("categoriesState")){var vm = App.Current.Resources["ODataViewModel"] as MyViewModel;string categoriesState = PhoneApplicationService.Current.State["categoriesState"] as string;vm.RestoreState(categoriesState);}}}private void Application_Deactivated(object sender, DeactivatedEventArgs e){// 保存相关数据,参见:“调用 OData 服务”var vm = App.Current.Resources["ODataViewModel"] as MyViewModel;PhoneApplicationService.Current.State["categoriesState"] = vm.GetState();}

Demo.xaml

<phone:PhoneApplicationPage x:Class="Demo.Communication.ODataClient.Demo"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"FontFamily="{StaticResource PhoneFontFamilyNormal}"FontSize="{StaticResource PhoneFontSizeNormal}"Foreground="{StaticResource PhoneForegroundBrush}"SupportedOrientations="Portrait" Orientation="Portrait"mc:Ignorable="d" d:DesignHeight="696" d:DesignWidth="480"shell:SystemTray.IsVisible="True"DataContext="{Binding Source={StaticResource ODataViewModel}}"xmlns:controls="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls"><phone:PhoneApplicationPage.Resources><DataTemplate x:Key="item"><ListBox ItemsSource="{Binding Products}"><ListBox.ItemTemplate><DataTemplate><Grid Width="460" HorizontalAlignment="Center"><Grid.ColumnDefinitions><ColumnDefinition Width="5*" /><ColumnDefinition Width="5*" /></Grid.ColumnDefinitions><StackPanel Orientation="Horizontal" VerticalAlignment="Center"><TextBlock Text="{Binding ProductName}" /><TextBlock Text="{Binding UnitPrice}" Margin="10 0 0 0" /></StackPanel><StackPanel Orientation="Horizontal" Grid.Column="1" HorizontalAlignment="Right"><Button x:Name="btnUpdate" Content="更新" Click="btnUpdate_Click" /><Button x:Name="btnDelete" Content="删除" Click="btnDelete_Click" /></StackPanel></Grid></DataTemplate></ListBox.ItemTemplate></ListBox></DataTemplate><DataTemplate x:Key="header"><TextBlock Text="{Binding CategoryName}" /></DataTemplate></phone:PhoneApplicationPage.Resources><Grid x:Name="LayoutRoot" Background="Transparent"><controls:Pivot x:Name="pivot"Title="产品列表" ItemTemplate="{StaticResource item}" HeaderTemplate="{StaticResource header}"ItemsSource="{Binding Categories}"></controls:Pivot></Grid><phone:PhoneApplicationPage.ApplicationBar><shell:ApplicationBar Mode="Default" IsVisible="True"><shell:ApplicationBarIconButton x:Name="btnAd" IconUri="/ApplicationBarDemo/Assets/appbar.add.rest.png" Text="添加" Click="btnAd_Click" /></shell:ApplicationBar></phone:PhoneApplicationPage.ApplicationBar></phone:PhoneApplicationPage>

Demo.xaml.cs

/** 调用 OData 服务的 View 层*/using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;using Demo.Communication.ODataClient.ViewModel;
using Demo.NorthwindContext;namespace Demo.Communication.ODataClient
{public partial class Demo : PhoneApplicationPage{public Demo(){InitializeComponent();this.Loaded += new RoutedEventHandler(Demo_Loaded);}void Demo_Loaded(object sender, RoutedEventArgs e){// 加载数据var vm = App.Current.Resources["ODataViewModel"] as MyViewModel;vm.LoadData();}private void btnDelete_Click(object sender, RoutedEventArgs e){var product = (sender as Button).DataContext as Product;// 删除指定的产品数据var vm = App.Current.Resources["ODataViewModel"] as MyViewModel;vm.DeleteProduct(product);}private void btnUpdate_Click(object sender, RoutedEventArgs e){// 更新指定的产品数据var product = (sender as Button).DataContext as Product;product.UnitPrice = 8.88m;var vm = App.Current.Resources["ODataViewModel"] as MyViewModel;vm.UpdateProduct(product);}private void btnAd_Click(object sender, EventArgs e){// 在指定的类别下添加一个新的产品数据var category = pivot.SelectedItem as Category;Product product = new Product();product.CategoryID = category.CategoryID;product.ProductName = "测试" + new Random().Next(10, 99);product.UnitPrice = 6.66m;product.Discontinued = false;var vm = App.Current.Resources["ODataViewModel"] as MyViewModel;vm.AddProduct(product);}}
}

OK
[源码下载]

与众不同 windows phone (29) - Communication(通信)之与 OData 服务通信相关推荐

  1. 与众不同 windows phone (32) - Communication(通信)之任意源组播 ASM(Any Source Multicast)...

    原文:与众不同 windows phone (32) - Communication(通信)之任意源组播 ASM(Any Source Multicast) [索引页] [源码下载] 与众不同 win ...

  2. 与众不同 windows phone (28) - Feature(特性)之手机方向, 本地化, 应用程序的试用体验, 系统主题资源, 本地数据的加密解密...

    原文:与众不同 windows phone (28) - Feature(特性)之手机方向, 本地化, 应用程序的试用体验, 系统主题资源, 本地数据的加密解密 [索引页] [源码下载] 与众不同 w ...

  3. 与众不同 windows phone (22) - Device(设备)之摄像头(硬件快门, 自动对焦, 实时修改捕获视频)...

    原文:与众不同 windows phone (22) - Device(设备)之摄像头(硬件快门, 自动对焦, 实时修改捕获视频) [索引页] [源码下载] 与众不同 windows phone (2 ...

  4. 与众不同 windows phone (40) - 8.0 媒体: 音乐中心的新增功能, 图片中心的新增功能, 后台音乐播放的新增功能...

    原文:与众不同 windows phone (40) - 8.0 媒体: 音乐中心的新增功能, 图片中心的新增功能, 后台音乐播放的新增功能 [源码下载] 与众不同 windows phone (40 ...

  5. 与众不同 windows phone (15) - Media(媒体)之后台播放音频

    原文:与众不同 windows phone (15) - Media(媒体)之后台播放音频 [索引页] [源码下载] 与众不同 windows phone (15) - Media(媒体)之后台播放音 ...

  6. 与众不同 windows phone (5) - Chooser(选择器)

    与众不同 windows phone (5) - Chooser(选择器) 原文:与众不同 windows phone (5) - Chooser(选择器) [索引页] [源码下载] 与众不同 win ...

  7. 与众不同 windows phone (14) - Media(媒体)之音频播放器, 视频播放器, 与 Windows Phone 的音乐和视频中心集成...

    原文:与众不同 windows phone (14) - Media(媒体)之音频播放器, 视频播放器, 与 Windows Phone 的音乐和视频中心集成 [索引页] [源码下载] 与众不同 wi ...

  8. 与众不同 windows phone (36) - 8.0 新的瓷贴: FlipTile, CycleTile, IconicTile

    原文:与众不同 windows phone (36) - 8.0 新的瓷贴: FlipTile, CycleTile, IconicTile [源码下载] 与众不同 windows phone (36 ...

  9. 与众不同 windows phone (23) - Device(设备)之硬件状态, 系统状态, 网络状态

    原文:与众不同 windows phone (23) - Device(设备)之硬件状态, 系统状态, 网络状态 [索引页] [源码下载] 与众不同 windows phone (23) - Devi ...

最新文章

  1. 6-5-树的双亲表示法-树和二叉树-第6章-《数据结构》课本源码-严蔚敏吴伟民版...
  2. TinyXml高速入口(一)
  3. postman test 脚本
  4. python能做自动化吗-Python自动化 作为代码小白,我是这样成为自动化大神的!...
  5. Matlab:绘制简单能量的接收机工作特性曲线(Energy_detection_simulation_ok)
  6. 压力测试和负载测试区别_如何理解与区分软件性能测试、负载测试、稳定性测试、压力测试...
  7. python字典函数_python-字典常用函数
  8. kmp算法next计算方法_KMP 算法详解
  9. DataGrid 绑定定制的列
  10. python的输出语句
  11. Innosetup 多种安装 vc_redist 运行库方式
  12. 如何低成本做好网络营销
  13. 一个简单的例子由易到难理解动态规划
  14. 黄金连分数(python)
  15. mysql入门很简单系列视频-学习笔记
  16. MapGuide源代码结构
  17. 中国信保总经理唐若疑卷入ST宏盛合同诈骗案昕下马
  18. soc验证 c语言,一种Soc芯片验证方法与流程
  19. 【LeetCode】1337. 矩阵中战斗力最弱的 K 行(C++)
  20. Thinkphp漏洞详解合集

热门文章

  1. 一起谈.NET技术,C# 中奇妙的函数之ToLookup
  2. 创建VLAN的两种方法
  3. 3/5 MySQL入门总结:数据库(DATABASE)操作
  4. Go语言 读写锁互斥锁原理剖析(2)
  5. 每日涉猎技术点存档(2019年02月)
  6. (转)JAVA正则表达式语法大全
  7. XCTF-高手进阶区:web2
  8. MOCTF-Web-机器蛇
  9. 设置背景图片模糊,内容不模糊
  10. echarts 环形图 默认高亮展示某个数据