Windows Phone 项目实战之我的微盘

不知道上一个项目实战Windows Phone 项目实战之账户助手》 大家学会创建自己的Windows Phone 应用程序没有?今天为大家带来另一个涉及网络的项目实战:我的微盘涉及的技术知识点有:JsonNetwork、本地上传文件、SDKHammock、微盘

用过新浪微博的朋友肯定很喜欢微盘 ,我们可以存储的文件并且与朋友分享,而且下载不需要任何积分(这点很重要,哈哈). 目前国内的网盘只有微盘是提供API给开发者的,我们可以自己写App来操作微盘,微盘的API地址为:http://vdisk.me/api (需要注册后才能查看)。

一、注册微盘账号

1.1、Step 1 注册微盘账户

打开网址:http://vdisk.me/?a=login#register ,输入邮箱及密码就可以创建微盘的账号

1.2、Step 2 登录微盘,创建微盘应用

注册成功后,登录网站,在首页的最下方找到API链接,点击后的url地址为http://vdisk.me/api  

点击创建新应用后会跳转到输入应用详细信息的页面,如下图:

  

 

输入完详细后,我们点击"创建"按钮,会提示你创建成功,然后我们就能在"我的应用"中找到App Key以及App Secret,有了这两个东西我们就可以使用微盘提供的API

1.3、Step 3 查看API,将自己所需要的API写为代码

 

二、Windows Phone 中处理JSON

在编写具体代码之前,先来看看文档中返回的数据,和发起的请求是什么样的。 如上图的"保持同步"接口,请求方式为POST或者GET,返回的结果是JSON格式的,同样下面的接口返回的数据都是JSON格式的。【以下的代码可以在这里找到】

那么我们如何将JSON格式变成我们熟悉的类呢?在Windows Phone 中我们有两种选择:

1. 使用System.Runtime.Serialization.Json命名空间下的DataContractJsonSerializer
2.
使用Newtonsoft.Json.WindowsPhone 类库

那么我们该如何选择呢?我的建议是如果你的应用中需要解析大量的JSON文件,这时候你可以选择第三方类库Newtonsoft.Json.WindowsPhone它提供更多的选择项给我们,但是如果只是解析个别的JSON文件,建议采用.NET类库中自带的JSON序列化类

下面来看看如何序列化JSON文件,我对两种方法都简单介绍下,其实用法大致一致,只不过 Newtonsoft.Json.WindowsPhone提供的可选择项较为丰富。如下图,如果我们需要把下述的json字符串变为一个ReturnResult

 2.1、使用DataContractJsonSerializer

需要将Json序列化为对象,我们需要一个类的定义,我们可以定义类如下:

 上述类的属性需要跟json字符串中的Key保持一致,大小写区分。当然我们也可以自定义类的属性,即可以与给定的Key不一致,这样方便我们查看 

使用 DataContractJsonSerializer需要添加System.ServiceModel.Web类库的引用,如果你使用DataContract模式的,我们还需要引用System.Runtime.Serialization类库的引用。

JSON字符串序列化为对象,我们需要一个类型为ReturnResult的序列化器,序列化器以流的形式读到对象的实例中,如下图

 如果采用第二种方式,只需要将typeofReturnResult)修改为typeofReturnResult2

在运行TestJson之前,我们在var result=serializer.ReadObject(ms);这一行打上断电,方便查看类中属性的值,可以看到与期望的效果一致。

2.2. 使用 Newtonsoft.Json.WindowsPhone

Newtonsoft.Json.WindowsPhone 的基本使用方法同DataContractJsonSerializer,下面用以Newtonsoft.Json.WindowsPhone序列化一个较为复杂的类介绍Newtonsoft.Json.WindowsPhone的使用方法。

 如上图所示,这样的数据结构不是一个类,而是一个类里面又有一个类,所以我们需要定义两个类

 

序列化的方法很简单,只需要一行代码就搞定

运行程序后,会发现result是我们所期望所转换的类。

2.3.两者区别

在使用自定义类属性上面二者存在一定的差别,使用 DataContractJsonSerializer需要对每个属性进行申明Attribute,而使用Newtonsoft.Json可以对单独的属性进行申明Attribute以实现自定义属性。如下图,我们建立两个新的类,分别用于这两种方法。
我们运行测试代码后,发现使用 DataContractJsonSerializer序列化的结果中有一个属性没有被解析出来,而Newtonsoft是正常解析的 
 Newtonsoft.Json.WindowsPhone
还有许多选项,由于篇幅有限,这里就不继续说了。

以上的代码可以在这里找到

三、网络请求

如今是网络的时代,也是移动的时代,网络和移动的结合更是趋势。由此诞生了很多的移动网络应用,从之前较为简单的WAP手机应用发展到现在的各种富互联网应用,更多许多优秀的移动应用客户端,诸如微博、QQ等客户端更是移动用户的必装软件,他们的共同点就是与网络打交道。在Windows Phone 开发中,有如下几种常用的方式进行网络交互。【下述代码点击这里下载】

3.1 使用WebClient

一般的代码格式如下:

申明一个WebClient实例,注册该实例的DownloadStringCompleted事件,然后发起异步请求即可。下面以博客园的订阅博客为例讲解如何在Windows Phone 中使用WebClient

下图是运行后的效果图,我们输入博主的名称,如alexis,点击"Get Blogs",查出的结果就是该博主近期的博客的订阅

点击按钮的处理代码如下

其中第一行代码是用于在SystemTray上显示当前信息,这在以前的博客中已提及。下面来看看注册的client_DownloadStringCompleted事件

在讲解上述代码之前,我们先来看看我们下载的数据源是什么样的,使用谷歌浏览器打开http://www.cnblogs.com/alexis/rss 就能看到数据源是基于XML格式的,由一个个item组成

这里是使用XML TO LINQ实现的,首先将下载下来得字符串转换为XML中的XElment,然后使用Linq将我们所需要的值的集合找出来,最后将集合作为ListBox的数据源以进行显示,RssItem的定义如下:

3.2 使用HttpWebRequest

上一节中讲解了WebClient的简单用法,WebClient是请求远程资源的最简单的方法,它实际上是对HttpWebRequest的进一步封装,隐藏了请求中的一些细节,而HttpWebRequest则可以让你了解请求的过程。

使用HttpWebRequest进行HTTP请求的步骤如下:
1.
创建HttpWebRequest的一个实例
2.
对请求流写入一些东西(如文件)如果你需要的话
3.
获得响应
4.
读取返回流中的数据
5.
关闭流

那么上述获得博客的例子可以利用HttpWebRequest重写如下:

3.3 使用第三方类库

对于REST服务请求的封装,第三方类库中Hammock以及RESTSharp都做得很好,我这里采用的是Hammock。我们这里只讲解Hammock的简单用法:

  1. 实例化RestClient对象
  2. 设置该对象的一些属性,如Authority
  3. 实例化一个RestRequest对象
  4. 添加RestRequest的请求参数
  5. 使用RestClient实例的BeginRequest方法进行异步请求
  6. 处理回调函数

更多的可以参考源代码

四、封装REST服务的API

我们查看微盘的API文档,发现提供了许多类型的请求,分别对应不同类型的操作。为了开发时和后期维护方便,我定义了一个枚举类型的服务类型,便于标识区分这些服务:

如上所述,使用REST服务的步骤就是发起一个请求,设置一些请求参数,然后坐等异步的回调,在回调中获得服务器返回的数据,从而进行处理。

4.1 获取Token

获取token与其他所有的请求不一样,他是所有其他请求的先决条件,我们只有获取到Token后才能发起其他请求:

这里我们需要传入我们应用的AppKey还有当前的时间戳,以下方法是在Windows Phone 中获取当前时间戳的方法:

另外,大家是否注意到,我们这里需要传入一个签名signature,大家应该都知道一般都是用签名来提高数据传输的安全性。因为token是十分机密的数据,如果让别人截获了token,他就可以对你的微盘进行任何操作。我们来看看API文档中是如何定义需要传入的signature的:

signature: 动态签名, hmac_sha256("account=相应的值&appkey=相应的值&password=相应的值&time=相应的值", app_secret)

对应的PHP实例: $signature = hash_hmac('sha256', "account={$account}&appkey={$appkey}&password={$password}&time={$time}", $app_secret, false);

有一个相应的算法,因为API网站中给出的是php的调用方法,hash_hmac是php中的一个函数,那么C#中有没有与之对应的函数呢?下面是获取签名的方法。

需要注意的是:

  1. 签名有时候需要全部大写,有时候是全部小写,需要我们转换一下
  2. 参数的顺序需要跟文档中保持一致

有了请求,我们只需要BeginRequest就可以获得相应的Response:

其中:

restClient是RestClient类的实例
Constants.ApiUrl为微盘的API地址
AsyncCallback为异步回调接收响应的函数,注意到我们这里传入了一个服务类型为ServiceType.GetToken,这样做的好处是我们可以使用一个单独的回调函数进行处理,而不要每一个请求对应一个回调函数。

上图是AsyncCallback的签名。下面来看看如何处理获得token

使用switch对请求类型以进行区分对待。我们使用Newtonsoft.Json中提供的JsonConvert对返回的数据进行序列化

其中,TokenResponse的定义如下

我们需要将获得的token和dologid保存,用于下次请求。 有了Token以后,我们才可以进行下面的请求。

Note:空闲时(不做任何操作, 15分钟后)token会失效

4.2 上传文件请求

微盘API中一般的请求都是路径和参数不一样的,为了方便管理,我这里新建了一个获取特定请求的帮助类,如下图是获取上传文件的请求:

其中UploadFileReq是封装的请求类,里面是一些传入请求中的参数,其定义如下图:

同获取Token的方法一样,我们只需要BeginRequest一下即可

注意要加上相应的服务类型ServiceType.UploadFile

其他的请求服务封装同上传文件,这里就不多说了,详细的可以查看源代码。

4.3 对外公布接口

封装接口后,我们需要对外面提供相应的接口,以方便Windows Phone 应用程序调用封装的类库。

4.3.1 登录接口

微盘所有的接口都是基于登录后获得的Token才能请求成功的,所以首先我们需要提供的就是登录的接口。查看API文档知道,调用登录接口(即获取Token)需要的参数值有如下几个:账号、密码、AppKey以及AppSecret。作为一个通用的SDK类库,我们需要提供接口让调用者设置一些相应的初始值,如AppKey、AppSecret。

我是提供了一个public的属性给外界,如下图

4.3.2 请求回调接口

大家是否注意到,对应请求的回调函数,我是统一用一个函数进行处理,以ServiceType进行区分判断,那么怎么将这个回调函数公布呢?这里我使用的一个委托,并定义一个该类型的公共属性,把这个公共属性作为对外的接口:

在回调中函数调用该属性

这样我们在Windows Phone程序中注册该委托就可以得到回调函数中的数据了。

五、应用SDK

我们封装好REST服务后,就可以在我们的Windows Phone应用程序中使用了。具体的方法如下:

因为基本上所有的API都是需要Token的,所以获取Token肯定是第一步,即调用SDK的获取Token方法:

其中,
Constants.AppKey即我们在微盘网站上申请的应用的AppKey
Constants.AppSecret即对应的AppSecret

然后就是调用服务的获取Token方法,需要传入用户名与密码。

大家是否注意到,我们给NetService实例的ServicecallBack属性赋值为登录回调函数:

由于登录有可能失败,所以我们也需要处理失败的情况。Note:如果是跨线程调用,则我们需要将改变UI线程的代码放在Deployment.Current.Dispatcher.BeginInvoke中。

下面来讲如何上传文件到微盘的接口,作为示例,我们将输入文本框的文字保存为文本文件上传到微盘中,页面的大致效果图如下

因为只有登录后才能上传文件,所以先讲Upload按钮设为不可用。

登录代码上面已经给出,我们在点击Upload按钮的时候需要做如下两件事情:

  1. 将输入框文本保存到独立存储空间中
  2. 将独立存储空间中的文件上传的微盘中

下述代码是创建一个文本,其中fileName为字符串常量

然后来看下按钮事件:

首先进行输入框中是否有输入,如果没有弹出提示框。然后在独立存储空间生成文本文件,最后就是调用微盘SDK的上传方法,输入相应的参数,指定回调函数

点击Upload,等了一会如果弹出提示"upload file succeed"的话,那么恭喜你,文件上传成功后,我们可以登录微盘check一下:

可以检查一下上传时间是不是现在的时间,当然你也可以重命名文件名。

六、后记

微盘中可能有个别接口没有实现,如果有兴趣贡献代码的可以跟我联系 。

微盘SDK for Windows Phone的源代码可以在vdisk.codeplex.com 上找到,谢谢你的支持

Updated: Windows Phone 实用开发技巧(22):使用日志记录当前信息与异常信息  、Windows Phone 实用开发技巧(24):上传日志

posted @ 2011-10-06 12:39 Alexis 阅读(...) 评论(...) 编辑 收藏