博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
与众不同 windows phone (29) - Communication(通信)之与 OData 服务通信
阅读量:6197 次
发布时间:2019-06-21

本文共 9388 字,大约阅读时间需要 31 分钟。

原文:

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

作者:
介绍
与众不同 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
{ public static void InitializeService(DataServiceConfiguration config) { // 全部实体全部权限 config.SetEntitySetAccessRule("*", EntitySetRights.All); // 指定服务所支持的 OData 协议的最大版本 config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2; } }}

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

/* * 调用 OData 服务的 ViewModel 层 *  * DataServiceCollection
- OData 服务的实体数据集合,添加、删除和更新数据时都会提供通知,继承自 ObservableCollection
* Count - 实体数据集合中的实体数 * CollectionChangedCallback - 实体集合更改时调用的委托 * EntityChangedCallback - 实体更改时调用的委托 * Continuation - 是否还有下一页数据 * LoadAsync(IQueryable
query) - 通过指定的查询异步加载数据 * CancelAsyncLoad() - 取消异步加载请求 * LoadNextPartialSetAsync() - 加载下一页数据 * Detach() - 停止跟踪集合中的全部实体 * LoadCompleted - 异步数据加载完成后触发的事件 * * * DataServiceState - 服务状态 * Serialize(DataServiceContext context, Dictionary
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
继承自 ObservableCollection
public DataServiceCollection
Categories { get; private set; } public void LoadData() { _context = new NorthwindEntities(_northwindUri); // 实例化 DataServiceCollection
,并注册相关事件 Categories = new DataServiceCollection
(_context); Categories.LoadCompleted += new EventHandler
(Categories_LoadCompleted); // 获取全部 Categories 数据,并且一次请求带上 Categories 的所有 Products DataServiceQuery
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
("Products").AddQueryOption("$filter", "ProductID eq 1"); // 异步请求 OData 服务 query.BeginExecute(p => { var myQuery = p.AsyncState as DataServiceQuery
; 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.cs public string GetState() { var dict = new Dictionary
(); dict["categories"] = Categories; return DataServiceState.Serialize(_context, dict); } // 恢复数据,当从 tombstone 状态进入 Activated 时,则从应用程序状态中恢复数据,参见 App.xaml.cs public void RestoreState(string appState) { Dictionary
dict; if (!string.IsNullOrEmpty(appState)) { DataServiceState state = DataServiceState.Deserialize(appState); // 获取相关数据 var context = state.Context as NorthwindEntities; dict = state.RootCollections; DataServiceCollection
categories = dict["Categories"] as DataServiceCollection
; // 恢复相关数据 _context = context; Categories = categories; Categories.LoadCompleted += new EventHandler
(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

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

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

你可能感兴趣的文章
遍历分区大小
查看>>
709. To Lower Case
查看>>
VC6.0之Debug调试总结
查看>>
面向对象设计:共性VS个性-------继承的粒度和聚合的粒度以及类的重构
查看>>
Android应用程序消息处理机制(Looper、Handler)分析(4)
查看>>
C++ 类成员的构造和析构顺序
查看>>
将String转化成Stream,将Stream转换成String
查看>>
POJ-1011 Sticks
查看>>
swat主流域文件(file.cio)参数详解——引自http://blog.sciencenet.cn/blog-922140-710636.html...
查看>>
支付宝接口错误:您使用的私钥格式错误,请检查RSA私钥配置,charset = utf-8
查看>>
娱乐一下:汤姆君的大转盘算法(搞笑版)
查看>>
java路径Java开发中获得非Web项目的当前项目路径
查看>>
(喷血分享)利用.NET生成数据库表的创建脚本,类似SqlServer编写表的CREATE语句...
查看>>
[译] 为用户提供安全可靠的体验
查看>>
卷积神经网络—基本部件(2)
查看>>
Android 系统开发_四大组件篇 -- 探讨 Activity 的生命周期
查看>>
各个大厂裁员情况,已经慌的一B
查看>>
php.类与对象
查看>>
想入门数据科学领域?明确方向更重要
查看>>
【速记】借助ES6的模版字符串,在不用Babel插件的情况下实现一个轻量级类JSX功能...
查看>>