您好,欢迎访问一九零五行业门户网

快速入门系列MVC07与HTML5移动开发的结合_html/css_WEB-ITnose

现在移动互联网的盛行,跨平台并兼容不同设备的html5越来越盛行,很多公司都在将自己过去的非html5网站应用渐进式的转化为html5应用,使得一套代码可以兼容不同的物理终端设备和浏览器,极大的提高了系统的可维护性和可扩展性。于此同时,html5提供了很多的新特性,比如新的架构元素、代替cookie的web存储技术、websocket等,也使得网站应用能够更好适应新的商业环境和技术更新。
本系统的网站模块使用.net技术堆栈中的asp.net mvc框架,此框架是微软公司推出的开源框架,相关源代码可以在codeplex.com网站上找到。该技术框架经过7年多的发展,当前已发展到5.1版本,新增了包括移动客户端模板、webapi模板、 oauth 认证等功能在内的新特性,便于当前的以互联网为主题背景的项目开发。
在实际的项目中,主要面临的两个问题分别是:实际用户使用的终端设备的厂商、型号等可能千变万化,如何在不同的web终端上呈现出适合的样式;asp.net mvc默认提供webform和razor两种视图引擎,但他们并不能支持html5页面的呈现,如何扩展视图引擎用于支持html5页面的渲染。实际选择的技术解决方案是,使用media queries等技术手段来实现响应式的css3设计,用自定义静态html5视图引擎扩展asp.net mvc框架。接下来,将分别详细介绍两个解决方案在项目中的实施应用。
首先,介绍响应式的网页布局,这个概念首先由ethan marcotte于2010年5月提出,目的是使得一个网站可以兼容多个终端—而不是为每一个终端开发一个特定的版本,可以说它就是为解决移动互联网相关痛点应运而生的。实际上,当前正在运营的很多大型网站上,仍然是维护多套的网站程序,有的还使用不同的域名来服务不同的终端。同时往往对移动端网页中的业务功能进行了一定的删减,虽然也能提供不错的用户体验,但这并不是最合理的解决方案,尽可能的统一用户接口是很有必要的。响应式的页面布局在具体的实现上,主要包含以下的几个步骤。
第一步,在html页面的head部分增加名为viewport的meta元素,viewport表示一个虚拟的窗口,通过它来设置适应移动设备屏幕的大小,代码如下所示。
1 2 view code
content属性中width=device-width,表示宽度为当前设备宽度;intial-scale=1表示初始缩放倍数为1,;user-scalable=0表示不支持用户手动缩放。同时增加css3-mediaqueries.js用于兼容ie6等老式浏览器。
第二步,使用media queries模块来根据不同的设备的可视屏幕大小来导入不同的css文件。该模块的应用需要修改两部分的内容,一部分是在html文件中增加3个不同条件下的css文件,另一部分是在css文件使用指定的形式将原有的内容包装起来。代码如下所示。
1 //html文件中:2 3 4 5 //css文件中:6 @media screen and (min-width:900px) {7 /*正常css内容,省略*/8 }view code
在html文件中,media属性中screen and (min-width:900px)表示媒体类型为屏幕,同时屏幕的最小宽度为900像素,only关键字使得不支持media queries的设备忽略该样式文件,之后href属性中为当前条件下所引用的css文件路径。通常来说屏幕可见宽度小于480像素的设备为手机,介于480像素到900像素之间的为平板电脑,大于900像素的为台式机电脑。在css文件中,通过添加@media段与页面中media属性进行映射,其块中所包含的内容与一般传统网站的该文件相似,针对不同的设备,通过继承的方式对样式的布局进行一些细节的调整。
最后一步,主要是处理前端开发中一些细节,包括使用相对的宽度,相对的字体大小、流动的布局、自适应的图片等内容,和传统的页面开发相似,在此就不一一展开。最终的效果图如下,可以看到同样的内容在不同的设备上得到不一样的渲染,以下是应用响应式页面布局技术的效果图。
接下来介绍如何在asp.net mvc框架中扩展自定义的视图引擎,使得框架能与html5技术无缝的衔接。之所以选择asp.net mvc框架作为web前端主要构件基础,除了之前所提到的一些支持移动互联网方面的新特性外,它内生所具备的高性能,高扩展性也起到了很大的作用。相对与重量级的webform框架,该框架显得非常的轻量级,使得页面渲染所消耗的资源得到了大幅的减少,并保留了认证、安全和本地缓存等模块的支持。此外,该框架提供了极强的扩展性,无论是自行修改框架,还是在已有项目中增减业务模块,都非常的方便。这一点,和java阵营的j2ee技术很相似,但同时又具有很高的稳定性和较高的开发效率。例如可以自定义url路由美化url并提升搜索引擎排名,自定义数据绑定支持不同数据格式的序列化和反序列化,自定义视图引擎应对不同的业务场景等。接下来,具体介绍如何实现自定义的html5视图引擎,包含以下的步骤。
第一步,创建自定义的html5视图。它是读取html5文件并呈现的基础,需要实现 system.web.mvc .iview 接口,并实现接口中的render方法,该方法主要通过流的方式读取指定的html5文件并渲染到页面,该部分内容比较简单,简化的代码如下所示。
1 public class html5view : iview 2 { 3 public string filename { get; private set; }//文件名 4 public html5view(string filename) 5 { 6 this.filename = filename; 7 } 8 9 public void render(viewcontext viewcontext, textwriter writer)10 {11 byte[] buffer = null;12 using (var fs = new filestream(this.filename, filemode.open))13 {14 buffer = new byte[fs.length];15 fs.read(buffer, 0, buffer.length);16 }17 writer.write(encoding.utf8.getstring(buffer));//读取文件并渲染18 }19 }view code
第二步,创建自定义缓存。由于html5fileview中都是静态的内容,很自然的需要构建相应的缓存用于提高性能。创建页面的缓存key对象html5viewcachekey,实现gethashcode方法,通过对controller和view的名称进行简单的hash组合运算等到缓存内容的key,并实现equals方法用于比较,简化的代码如下所示。
1 public class html5viewcachekey 2 { 3 public string controllername { get; private set; } 4 public string viewname { get; private set; } 5 public html5viewcachekey(string controllername, string viewname) 6 { 7 this.controllername = controllername string.empty; 8 this.viewname = viewname string.empty; 9 }10 11 public override int gethashcode()12 {13 return this.controllername.tolower().gethashcode() ^ this.viewname.tolower().gethashcode();14 } 15 16 public override bool equals(object obj)17 {18 html5viewcachekey key = obj as html5viewcachekey;19 if (null == key)20 return false;21 return key.gethashcode() == this.gethashcode();22 }23 }view code
第三步,创建视图引擎html5viewengine。该类实现了iviewengine接口,字典类viewengineresults结合第二步中构建的缓存类用于缓存渲染后的视图。方法findview首先解析路由信息获得控制器的名称,之后判断请求是否支持缓存,若不支持缓存,则直接通过 internalfindview 方法 获得视图。反之,判断请求视图是否在本地缓存中,若存在直接返回,若不存在则调用方法获取并缓存,写缓存时注意加锁。 internalfindview 方法中,借助面向约定编程的思路到指定的路径中寻找到对应的文件html5,最终完成url信息与文件的映射。
1 public class html5viewengine : iviewengine 2 { 3 private dictionary viewengineresults = 4 new dictionary(); 5 private static object synchelper = new object(); 6 7 public viewengineresult findpartialview(controllercontext controllercontext, string partialviewname, bool usecache) 8 { 9 return this.findview(controllercontext, partialviewname, null, usecache);10 }11 12 public viewengineresult findview(controllercontext controllercontext, string viewname, string mastername, bool usecache)13 {14 string controllername = controllercontext.routedata.getrequiredstring(controller);15 var key = new html5viewcachekey(controllername, viewname);16 viewengineresult result = null;17 if (!usecache)//是否支持缓存18 {19 result = internalfindview(controllercontext, viewname, controllername);20 viewengineresults[key] = result;21 return result;22 }23 if (viewengineresults.trygetvalue(key, out result)) //视图是否已经在缓存中24 {25 return result;26 }27 28 lock (synchelper)//锁定视图数据写入缓存过程29 {30 if (viewengineresults.trygetvalue(key, out result))31 {32 return result;33 }34 result = internalfindview(controllercontext, viewname, controllername);35 viewengineresults[key] = result;36 return result;37 }38 }39 40 private viewengineresult internalfindview(controllercontext controllercontext, string viewname, string controllername)41 {42 string[] searchlocations = new string[]{43 string.format(~/staticviews/{0}/{1}.html, controllername.tolower(), viewname.tolower()),44 string.format(~/staticviews/shared/{0}.html, viewname.tolower())45 };46 47 string filename = controllercontext.httpcontext.request.mappath(searchlocations[0]);48 if (file.exists(filename))49 {50 return new viewengineresult(new html5view(filename), this);51 }52 filename = string.format(@\staticviews\shared\{0}.html, viewname.tolower());53 if (file.exists(filename))54 {55 return new viewengineresult(new html5view(filename), this);56 }57 return new viewengineresult(searchlocations);58 }59 60 public void releaseview(controllercontext controllercontext, iview view)61 {62 }63 }view code
最后一步,将视图自定义的视图引擎添加到global.asax文件的application_start方法中,完成该引擎的注册。同时注意需要将该引擎的优先级设为最高,使得系统优先使用该引擎对视图相关请求进行响应。
1 public class mvcapplication : system.web.httpapplication2 {3 protected void application_start()4 {5 //省略6 viewengines.engines.insert(0, new html5viewengine());7 }view code
通过以上步骤,基本上将asp.net mvc框架,html5技术,移动互联网开发技术有机的整合到了一起。
tip: 本文由于是学习需要,主要参考了以下书目。
[1]蒋金楠. asp.net mvc4框架揭秘[m]. 上海:电子工业出版社, 2012. 419-421
[2]唐俊开. html5移动web开发指南[m]. 上海:电子工业出版社, 2012. 52-54
其它类似信息

推荐信息