[原创]用.Net打造一个移动客户端(Android/IOS)的服务端框架NHM(二)——“请求”“交互”与传输数据(服务器端)
作者:洪洋
本章目的
上一章,我们对目前移动互联网客户端与服务点数据交换的两种技术进行了简要的分析,从本章开始,我们将进入正式的内容,开始逐步搭建服务端框架。这一章,我们着重解决服务端与客户端如何交互的一些原理和概念性问题。
服务端结构
首先我们来看一个图:
客户端与服务器交互,使用http协议是最简单易用的方法。完整的过程应该是这样:
1、客户端通过http协议访问服务器的一个页面,如:http://localhost:8080/api/getuser.aspx?id=1
2、服务器经过处理后,把这个页面生成为仅有json数据的文本流
3、客户端得到JSON流后,反序列化为对象、显示等等
服务端的三层结构,在数据访问方面,我们这里采用LINQ技术与数据库互动。LINQ确实是一种很方便的数据访问技术,虽然它存在一些的设计模式的问题,就是在Model层中混杂了DAL的成分,而大量的LINQ语句出现在BLL中看起来也十分别扭。但是你不可否认微软的Linq技术确实有效的解决了.NET体系中缺少如nhibernate这样的ORM的问题,在此之前,如果要构建.net三层结构,需要书写大量的Model,DAL,完全无技术含量的重复劳动;或者采用像nhibernate这样的第三方框架。LINQ的出现解决了这样的问题,但微软在易用性和理论之间,偏向了易用性。另外,从2011年12月10日的视野来看,LINQ也是昨日黄花的技术了,取而代之的是ADO.NET EntityFramework——EF。在这里,我们依然使用LINQ作为与数据库交互的主要手段。EF与Linq其实很相似,如果读者感兴趣,可以尝试改变。
数据访问的问题解决后,就要解决LINQ TO JSON的问题,即——序列化。那么采用什么的方案进行序列化呢?目前主要有下面三种方式:
1、.NET JSON代码段:在网上随便搜索“.net json关键字”可以查到最多的,就是一些为.net 2.0写的json helper,很遗憾,这些helper基本都只能转换传统的.net数据对象,如datatable,有的根本不能的实现object to json(其实这才是json最有魅力的地方,不知为何很多helper没有实现,其使用反射很简单实现泛型的序列化的,不过后面有现成的方案,我们就不用自己造轮子了……),另外还有一些其他bug,如空子段处理错误(必须使用 JSON 文本“null”表示所有 null 值)、日期格式错误等,所以这些json helper请读者直接忽略。(此点本不值一提,不过怕读者走弯路,还是说一下好些)。
2、.NET官方的 System.Runtime.Serialization.Json,这个类库从.Net 3.5开始加入,在.Net4.0做了极大的扩展。但作者并没有仔细研究过它,感兴趣的读者可以到MSDN查看:独立 JSON 序列化。
3、Newtonsoft.JSON 这个类库是较早出现的.net json解决方案,已经较为成熟,在.Net JSON中应用十分广泛,目前已经开源,支持LINQ to JSON,我们就使用这个。项目地址:Json.NET CodePlex Project
解决了数据库和JSON,基本解决了服务端的技术问题,下面让我们来进入实践阶段。
实践:Northwind Android APP 服务端
(一)搭建开发环境
1、数据库服务器采用MS SQLServer2005,采用SQLServer2000的样例数据库,Northwind。下载地址:Northwind and pubs Sample Databases for SQL Server 2000
2、配置一个IIS服务器,能在局域网内或本机通过ip或机器名正常访问,如:http://localhost:8080/
3、安装VisualStuido 2010配置好开发环境
4、安装Eclipse + Android SDK
一些注意事项:
1、可不可以不配置IIS而直接通过VisualStuido中的内置的ASP.NET Developent Server完成调试工作?
答:理论上当然可以,但实在不推荐这样。因为这样不方便在Eclipse上用android模拟器访问到Web Server,主要是ASP.NET Developent Server端口号不固定,而且不一定是一直开启的状态。
2、如何配置IIS?
答:把iis的网站根目录指向解决方案的WebApplication项目、配置好应用程序池,保证在开发过程中都可以用 http://localhost:8080/ 这样的方式访问到最新的站点。
3、Eclipse + Android 开发环境需要注意什么?
答:如果你的IIS服务器和Eclipse在同一台机器上(大部分读者的情况应该是这样吧),如果要用Android模拟器访问localhost,你需要访问"10.0.2.2" 这个IP,其他方式均无法访问。后面讲Android端开发时会涉及到个内容。
(二)建立解决方案
好了,开发环境搭建好了,现在可以开始建立.NET 项目。建立.NET解决方案,添加必要的项目,注意项目间的引用关系(没有的暂时不考虑),建立好解决方案后,把WebApplication设成启动项目。
(三)建立JSONProvider
1、添加对Newtonsoft.Json的引用
2、新建一个NetwonJsonHelper.cs静态类,便于封装一些自己常用的方法
3、添加新的静态方法LinqToJson(object o)
public static string LinqToJson(object o) { string rtn = ""; rtn = JArray.FromObject(o).ToString(); return rtn; }可以看到实在是太简单了。这里要解释一下JsonArray和JsonObject,顾名思义Array是Object的数组,JsonObject一般是这样的{"key":"value"},而JsonArray则是这样的 [JsonObject,JsonObject],也就是说JsonObject是"{"开头的,而JsonArray则是"[",这一点要记住了,否则可能会在反序列化的时候出现问题。
(四)建立Encrypt
我们需要一个项目来处理加密和解密的问题,于是便有了Encrypt。它最主要的作用,是在http传输的过程中对所有内容进行加密,这包括客户端请求服务器的内容(必须加密)和服务器返回给客户端的内容(可以加密)。这里你可以扩展你自己的加密算法以便起到保密性的作用,但无论你采用什么样的加密算法,最外一层作者建议一定要用base64包装一下,这是为了保证传输的有效性。
这里我们并没有采用.Net Framework中的加密类,而采用了手工写的Base64是有原因的,因为要进行web传输,所以url会对base64中的 "/" "+" 比较敏感,所以我们要在Base64字符集中替换/ +为其他字符,另外,通过调整字符集的顺序,也可以起到一定的加密作用。
(五)接下来建立LINQ的DataClasses
在Model层,新建一个DataClasses.dbml,把Northwind数据库的Employees表拖进dbml。
在BLL层建立 EmployeeEntity.cs,它是雇员表的业务逻辑层,暂时只包括一个通过ID查找雇员的构造方法和一个JSON序列化的公共方法。
public class EmployeeEntity { public List<Employees> EmployeesList = new List<Employees>(); private DataClassesDataContext dc = new DataClassesDataContext(); public EmployeeEntity() { } public EmployeeEntity(int id) { var cs = from c in dc.Employees where id == c.EmployeeID select c; EmployeesList = cs.ToList(); } public string toJson() { string rtn = ""; rtn = NetwonJsonHelper.LinqToJson(EmployeesList); return rtn; } }
(六)测试服务端
服务端的准备工作基本结束,我们来测试下
1、在WebApplication项目中建立default.aspx
2、前台代码如下:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication.Default" %> <asp:literal id="lt_rtn" runat="server"></asp:literal>3、后台代码如下:
protected void Page_Load(object sender, EventArgs e) { EmployeeEntity ee = new EmployeeEntity(1); lt_rtn.Text = ee.toJson(); }
说明:前台代码要保证不生成任何html字符,使用liture,去掉form,都是这个目的(如果读者提出应该禁用viewstate是多余的,没有form就没有viewstate)。后台代码就是简单取一个Employee对象转化为json,让我们看下结果:
可以看到,执行的结果是JSON成功转换,并且没有任何多余代码。客户端可以通过请求类似default.aspx这样的页面获得自己想要的json.
小结
这一章,我们主要完成了服务器的环境搭建工作,通过LINQ+JSON,我们已经可以给客户端提供必要的信息了。下一章我们将开始Android的JAVA端开发之旅。