zoukankan      html  css  js  c++  java
  • 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):上传日志

    如果您喜欢我的文章,您可以通过支付宝对我进行捐助,您的支持是我最大的动力https://me.alipay.com/alexis


    作者:Alexis
    出处:http://www.cnblogs.com/alexis/
    关于作者:专注于Windows Phone 7、Silverlight、Web前端(jQuery)。
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,如有问题,可以通过shuifengxuATgmail.com  联系我,非常感谢。

  • 相关阅读:
    【贪心】【堆】Gym
    【并查集】Gym
    【拓扑排序】【bitset】Gym
    【递归】【线段树】【堆】AtCoder Regular Contest 080 E
    【二分图】【并查集】XVII Open Cup named after E.V. Pankratiev Stage 14, Grand Prix of Tatarstan, Sunday, April 2, 2017 Problem L. Canonical duel
    【动态规划】【滚动数组】【bitset】XVII Open Cup named after E.V. Pankratiev Stage 14, Grand Prix of Tatarstan, Sunday, April 2, 2017 Problem J. Terminal
    【二分】【字符串哈希】【二分图最大匹配】【最大流】XVII Open Cup named after E.V. Pankratiev Stage 14, Grand Prix of Tatarstan, Sunday, April 2, 2017 Problem I. Minimum Prefix
    【枚举】【最小表示法】XVII Open Cup named after E.V. Pankratiev Stage 14, Grand Prix of Tatarstan, Sunday, April 2, 2017 Problem F. Matrix Game
    【推导】【构造】XVII Open Cup named after E.V. Pankratiev Stage 14, Grand Prix of Tatarstan, Sunday, April 2, 2017 Problem E. Space Tourists
    【推导】【贪心】XVII Open Cup named after E.V. Pankratiev Stage 14, Grand Prix of Tatarstan, Sunday, April 2, 2017 Problem D. Clones and Treasures
  • 原文地址:https://www.cnblogs.com/alexis/p/2199772.html
Copyright © 2011-2022 走看看