基于ASP.NET MVC 3的企业应用项目总结

  为期三个月的开发加测试工作终于告一段落了,这是我们团队第一次采用ASP.NET MVC(直接使用最新的MVC 3)开发企业应用,期间碰到了很多问题,但在大家的努力下,也都一一解决,先简单介绍一下项目情况吧,是公司的一套业务运营系统,总的从技术实现难度来讲,没有什么特殊的地方,只有相关部分的业务逻辑算法比较复杂。项目开始前,最大的风险在于整个team除了另外一名同事和我使用过MVC,其他人都是第一次使用,并且另外那名同事在项目开始一个月左右离职了~~!好在通过大量的交流沟通、code review、内测等手段下,项目基本成功完成。

一、技术架构介绍

  基于.Net的多层解决方案,web框架采用了微软的ASP.NET MVC 3(视图引擎为Razor),数据层采用Entity Framework 4.0。界面组件方面使用了Telerik for MVC版本,JS框架依然是强大的JQuery。 系统提供了中、英两套语言版本,采用微软官方推荐的多语言解决方案,该方案很容易扩展其他语言版本。

二、MVC

  个人感觉ASP.NET MVC 3相比2和1,并没有带来革命性的变化,但一些小的改进还是相当不错的,也提高了不少开发人员的效率。
以下列表显示了我们用到的一些ASP.NET MVC的特性(包括ASP.NET MVC 3但不限于3)
1. 基于layout的页面结构,一个首页可以拆分成如下: 包含title、head、body、以及公用JS、CSS文件的最顶层layout。 包含菜单导航的分部视图(Partial View) 包含主页面内容的View。 主页面里又可以包含其他公共的分部视图,或为了层次更清晰而人为拆分的逻辑部分视图(设计合理的部分视图有利于提高代码层次的清晰程度,但过多的使用也会降低系统性能,毕竟多了一些IO操作)。
2. 通过使用ViewResult、ActionResult、PartialResult、JsonResult输出不同的内容。
3. 新增了Dynamic特性,配合Razor可以很方便的在视图上使用控制器提供的数据。
4. MVC Chart组件可以很方便的输出比较专业的图表。
5. 控制器基类提供了很多重写方法,可以较为方便的进行一些全局的处理,例如:异常、方法级别的注入等。
6. unobtrusive js,通过服务器端ModelMetadata和客户端的unobtrusive js,可以做到前后台的统一验证,大大减少开发量。

三、Razor

  采用了微软最新的Razor(模板引擎语言)配合MVC3进行开发,新一代的视图引擎Razor以简洁的“@”开头的写法,对强类型的智能感知做的也非常不错(不过在JavaScript代码部分的智能感知还是有些问题)。 相比ASPX视图引擎,Razor还是胜在简洁上,也有第三方的NVelocity模板引擎,虽然语法也很简洁,但智能感知方面就做的比较差了,因此,开发ASP.NET MVC 3,Razor还是首选。 至于性能上的比较,没有实际分析过,可能会比ASPX略逊一些。
总结Razor的优点如下:
1. 代码流畅简洁。
2. 与HTML结合很顺畅,不需要单独处理大括号。
3. 代码高亮显示。
4. 很方便的输出单行文本(@:)或多行文本()。

四、Entity Framework

  数据层采用微软提供的ORM框架Entity Framework,并配合Linq To Entity,能够以简洁的linq语句或lambda表达式,来代替复杂冗长的SQL语句。 总体上来讲EF相比Linq To SQL,并没有特别大的不同,其中结合Validation类来对Model进行MetadataType的标记,来实现数据的校验,感觉是一个比较不错的方式。更能体现代码单一职责原则,我们不必要在控制器里写大量的校验逻辑。
  EF的edmx文件在从数据库更新的时候,容易出现更新不成功的情况,这时候则需要将实体删除并从数据库新增就可以解决这个问题。 对于EF的DBContext,在不同层传递的时候,应该尽量一致,个人更倾向于实例化对象的方式,而且比较好的实践方式是: 在业务层持有一个全局的数据层对象引用,在控制器里使用实例化的业务层对象对数据库进行读写操作。 在项目的前期,因为大量使用了数据层或业务层的静态方法,以至于在业务逻辑相对简单的系统管理模块出现了大量的bug,主要的原因就是数据上下文使用混乱,前后不一致,应该说是我们的一个教训。 需要谨慎处理延迟加载,以降低性能方面的影响。什么时候需要延迟加载、什么时候不需要延迟加载,感觉还是跟具体的业务逻辑有关,不能一概而论。 数据对象的使用也是要考虑的一方面,尤其是在前台更改了某些数据属性之后,在同一个上下文里进行数据保存操作后,可能会出现你所不期望的修改。尤其是在复杂的业务计算类库上面,一个对象经过重重传递,很容易出这个问题,并且不太好查。

总结:要明确的知道数据对象的使用范围。

五、AOP

  对于ASP.NET MVC 3来讲,天生就是支持AOP的,框架自带的ActionFilterAttribute基类提供了四个重载方法,
如下所示:
1. public virtual void OnActionExecuted(ActionExecutedContext filterContext) 该方法在Action执行之后触发。
2. public virtual void OnActionExecuting(ActionExecutingContext filterContext) 该方法在Action执行之前触发。
3. public virtual void OnResultExecuted(ResultExecutedContext filterContext) 该方法在Result渲染完之后触发。
4. public virtual void OnResultExecuting(ResultExecutingContext filterContext) 该方法在Result渲染之前触发。

通过这四个重载方法,可以非常方便的将代码逻辑织入到Action的生命周期内。 对于我们这个系统,实现了如下几个方面的织入:
1. 功能权限控制。
2. 数据权限控制。
3. 项目状态检查。
4. 操作日志。

AOP带来的好处也是显而易见的,减少代码量、降低业务逻辑和非业务逻辑代码的耦合度、便于维护。

六、Telerik

  为了提高开发效率和复用代码,在界面上也大量的使用了Telerik控件for ASP.NET MVC版本。
主要有如下应用:
DatePicker,日期选择组件,其中可以设置可以选取的范围是亮点,但其本身绑定的一些事件也是有利有弊(例如Onblur之后的自动设置日期值),客户端不能灵活的控制。
Window,仿模态窗口,弹窗利器。
Grid,表格组件,功能很强大,但有些特殊场景还是很别扭。同样是客户端控制程度不够。
TreeView,树组件,功能也很强大,很好用。

总结:有一套好的可复用组件确实能大大提高开发效率,但前提是要对其有较好的把控能力,否则容易适得其反。

七、多语言解决方案

  采用微软官方推荐的资源文件做法,我们这个系统有中、英文两个版本,则在所有的显示字段、交互提示等地方,全部使用了资源文件标签。 其原理就是根据用户选择的语言种类(存到cookie),动态设置当前线程的语言环境,剩下的事情微软已经帮我们做好了,实现起来很简单,推荐使用。

关键代码:

HttpCookie hk = Utils.Language.GetLangCookie(); 
string langName = ""; 
if (hk != null) 
{ 
langName = hk.Value; 
} 
else 
{ langName = "zh-cn"; } 
CultureInfo cultureInfo = new System.Globalization.CultureInfo(langName);
System.Threading.Thread.CurrentThread.CurrentUICulture = cultureInfo;
System.Threading.Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(cultureInfo.Name);

八、其他:log4net、NPOI

  同时也采用了一些其他优秀的开源框架: 使用log4net来记录异常日志和一些操作日志,使用npoi来进行excel操作。这两个框架都是从JAVA平台移植过来,不得不说,JAVA社区在开源框架方面的研究要胜于.Net。

九、未来考虑

  引入Ioc框架:为了降低业务层与数据层、控制器之间的耦合,使代码更灵活以及更容易扩展和维护,考虑后续引入IOC框架(例如:unity、spring.net、castle windsor等)
  采用独立缓存服务器:一直以来,缓存都是提升系统性能最廉价的解决方案,目前我们需要缓存的数据量较小,直接使用.Net自带缓存进行缓存处理,例如:组织机构、功能菜单等,虽然.NET自带的缓存功能很强大,但毕竟和app server共用内存,且处于同一应用程序域内,如果在缓存使用较多的情况下,性能不是很理想。未来考虑使用分布式缓存,例如:memcache、redis等优秀的第三方缓存框架。
  更好的用户体验,主要体现在优化部分操作流程和页面操作体验。
  WCF重构部分服务以支撑更多不同类型的客户端。

posted @ 2011-08-27 09:22  L.Qiu  阅读(3274)  评论(10编辑  收藏  举报