ASP.NET MVC 2框架试用经验谈

开发 后端
本文将为大家讲述的是ASP.NET MVC 2框架试用经验,希望通过本文能对大家有所帮助。

本文将为大家介绍已经发布的ASP.NET MVC 2框架正式版的使用情况,包括缓存,静态内容的放置等等。希望本文能对大家有所帮助。

这个月一直在用 ASP.NET MVC 2 做http://www.86e0.com/t 这个网站,用的时候是 aps.net MVC2 RC2,然后现在ASP.NET MVC 2正式版已经是发布了。 在MVC的使用上,有一些心得。下面作一下总结,希望对大家有用,也欢迎大家讨论。

1.关于缓存

缓存上,数据层上的缓存是必须的,这点不必多说了。

另一个很重要的是:视图片段缓存。

我参考了老赵的写的三篇关于片段缓存的文章:

适合ASP.NET MVC的视图片断缓存方式(上):起步

适合ASP.NET MVC的视图片断缓存方式(中):更实用的API

适合ASP.NET MVC的视图片断缓存方式(下):页面输出原则

本想用老赵的了,但是我发现ASP.NET MVC 2 的有一个新功能: Html.Partial可以返回生成的HTML, 返回的类型是:MvcHtmlString. 虽然要利用Partial View才能生成Html片段,但是我想这个已经够我用的了, 所以我做了一个这样一个Helper,主要是将生成的HTML片段缓存到Memcached里。代码如下:

  1. public static class MvcHtmlHelper   
  2. {   
  3. public static MvcHtmlString MemcacheHtmlPartial(this HtmlHelper htmlHelper,int duration, string partialViewName, object model, ViewDataDictionary viewData)   
  4. {   
  5. object obaear = htmlHelper.ViewContext.RouteData.DataTokens["area"];   
  6. string area=string.Empty;   
  7. if (obaear != null) area = obaear.ToString();   
  8. string key = string.Format("MemcacheHtmlPartial_{0}{1}", area, partialViewName);   
  9. object ob = DistCache.Get(key);   
  10. if (ob == null)   
  11. {   
  12.  MvcHtmlString mstr = htmlHelper.Partial(partialViewName, model, viewData);   
  13.  DistCache.Add(key, mstr.ToString(), TimeSpan.FromSeconds(duration));   
  14. return mstr;   
  15. }   
  16. else 
  17. {   
  18.  return MvcHtmlString.Create((string)ob);   
  19. }   
  20.  }   

然后,我觉得,这样,在每次请求时,还是要在Controller 里把数据取出来,然后再传到 Partial View里。 既然已经缓存了,就应该不用每次请求都要在Controller里把数据取出来才对!虽然数据层会有缓存。

所以我,能不能再省下去Controller取数据的消耗,于是又有了以下代码,其功能是:缓存Action生成的HTML到Memcached里。

  1. public static MvcHtmlString MemcacheHtmlRenderAction(this HtmlHelper htmlHelper, 
  2. int duration, string actionName,string controllerName, RouteValueDictionary routeValues)   
  3. {   
  4. object obaear = htmlHelper.ViewContext.RouteData.DataTokens["area"];   
  5. string area = string.Empty;   
  6. if (obaear != null) area = obaear.ToString();   
  7. string key = string.Format("MemcacheHtmlRenderAction_{0}{1}{2}", area, controllerName,actionName);   
  8. object ob = DistCache.Get(key);   
  9.  if (ob == null)   
  10.  {   
  11.  // htmlHelper.RenderAction(actionName, controllerName, routeValues);   
  12. StringWriter writer = new StringWriter(CultureInfo.CurrentCulture);   
  13.  ActionHelper(htmlHelper, actionName, controllerName, routeValues, writer);   
  14. string wStr = writer.ToString();   
  15. DistCache.Add(key, wStr,TimeSpan.FromSeconds(duration));   
  16. MvcHtmlString mstr = MvcHtmlString.Create(wStr);   
  17. return mstr;   
  18.  }   
  19. else { return MvcHtmlString.Create((string)ob); }   

说明一下,Actionhelper的方法是在MVC原代码里提取出来的。 因为MVC2里的 Html.RenderAction方法并没有返回 MvcHtmlString的重载版。那位有更好的方法?

其实,MVC里的Action有输出缓存,所以直接在View里用 Html.RenderAction都可以解决很多问题了。这个主要是可以用程序管理缓存。

2.关于静态内容的放置

习惯上,静态内容会放在 mvc程序所在的目录下,比如说js,css,上传的图片等。但是这样的话,所有的静态请求都要经过 aspnet_isapi 处理,这样是非常不合算的。所以静态内容一般都会放在另外的子域上。http://www.86e0.com/t 是放在 cdn.86e0.com上。

3.关于强类型ViewModel

我基本上看了老赵的Asp.net MVC***实践。 其中有一点,就是强烈推荐使用强类型的ViewModel. 我试了一些页面,发现用强类型的ViewModel,现阶段并不适用于我。因为我是用NbearLite,从数据库抓出来的大多是DataTable. 我是觉得DataTable+NbearLite蛮方便的,虽然没有动态语言的数据访问来得方便,但是比用Entity,ViewModel, DTO,等等来说,还是可以省下很多代码。然后,最重要的是,由于我这种站经常会修改,所以数据库改变,加字段,减字段是很经常性的事。但是,用NbearLite + DataSet,DataTable,却非常方便。

所以我觉得,做Asp.net MVC,如果你不是用DDD,DDT的话,用DataTable还是可以的。因为DDD,DDT学习起来还是要点成本的。

4.关于URL生成

URL生成, 老赵写了一系列文章:

各种URL生成方式的性能对比

各种URL生成方式的性能对比(结论及分析)

为URL生成设计流畅接口(Fluent Interface)

URL生成方式性能优化结果

我直接选择

Raw方式了, 速度最快的,才是适合我的。呵。 而不是强类型的才是适合我的。

***,分享一个很实用的Asp.net MVC 分页Helper.

这个Helper引自重典老大的blog:http://www.cnblogs.com/chsword/ . 我在之前做了少少修改,现已经在http://www.86e0.com/t 上使用了。

效果如下:

image

请大家注意生成的 URL, 是用 ?参数=页码 的方式。代码如下:

  1. /// <summary>   
  2. /// 分页Pager显示   
  3. /// </summary>   
  4. /// <param name="html"></param>   
  5. /// <param name="currentPageStr">标识当前页码的QueryStringKey</param>   
  6. /// <param name="pageSize">每页显示</param>   
  7. /// <param name="totalCount">总数据量</param>   
  8. /// <returns></returns>   
  9. public static string Pager(this HtmlHelper html, string currentPageStr, int pageSize, int totalCount)   
  10.  {   
  11. var queryString = html.ViewContext.HttpContext.Request.QueryString;   
  12. int currentPage = 1; //当前页   
  13. if(!int.TryParse(queryString[currentPageStr], out currentPage)) currentPage = 1; //与相应的QueryString绑定   
  14.  var totalPages = Math.Max((totalCount + pageSize - 1) / pageSize, 1); //总页数   
  15. var dict = new RouteValueDictionary(html.ViewContext.RouteData.Values);   
  16. var output = new StringBuilder();   
  17. foreach (string key in queryString.Keys)   
  18. if (queryString[key] != null && !string.IsNullOrEmpty(key))   
  19. dict[key] = queryString[key];   
  20. if (totalPages > 1)   
  21. {   
  22. if (currentPage != 1)   
  23. {//处理首页连接   
  24. dict[currentPageStr] = 1;   
  25. output.AppendFormat("<span class=\"p_home\">{0}</span>", html.RouteLink("首页", dict));   
  26.  }   
  27.  if (currentPage > 1)   
  28. {//处理上一页的连接   
  29. dict[currentPageStr] = currentPage - 1;   
  30. output.AppendFormat("<span class=\"p_up\">{0}</span>", html.RouteLink("上一页", dict));   
  31. }   
  32.  else 
  33. {   
  34.  output.AppendFormat("<span class=\"p_disable\">{0}</span>","上一页");   
  35.   }   
  36. int currint = 5;   
  37.  for (int i = 0; i <= 10; i++)   
  38.  {//一共最多显示10个页码,前面5个,后面5个   
  39. if ((currentPage + i - currint) >= 1 && (currentPage + i - currint) <= totalPages)   
  40.  if (currint == i)   
  41. {//当前页处理   
  42.  output.Append(string.Format("<span class=\"p_current\">{0}</span>", currentPage));   
  43.  }   
  44.  else 
  45.   {//一般页处理   
  46. dict[currentPageStr] = currentPage + i - currint;   
  47. output.AppendFormat("<span class=\"p_num\">{0}</span>",html.RouteLink((currentPage + i - currint).ToString(), dict));   
  48.    }   
  49.    }   
  50.  if (currentPage < totalPages)   
  51.    {//处理下一页的链接   
  52.     dict[currentPageStr] = currentPage + 1;   
  53.      output.AppendFormat("<span class=\"p_down\">{0}</span>", html.RouteLink("下一页", dict));   
  54.    }   
  55.     else 
  56.       {   
  57.       output.AppendFormat("<span class=\"p_disable\">{0}</span>""下一页");   
  58.    }   
  59.    if (currentPage != totalPages)   
  60.     {   
  61.    dict[currentPageStr] = totalPages;   
  62.      output.AppendFormat("<span class=\"p_last\">{0}</span>",html.RouteLink("末页", dict));   
  63.    }   
  64.     }   
  65.   output.AppendFormat("<span class=\"p_count\">第{0}页/共{1}页</span>", currentPage, totalPages);//这个统计加不加都行   
  66.    return output.ToString();   
  67.   }  

ASP.NET MVC延伸阅读

ASP.NET MVC是微软官方提供的MVC模式编写ASP.NET Web应用程序的一个框架。

它由Castle的MonoRail而来.目前已经历经数个版本。ASP.NET MVC中的MVC本来是存在于Desktop程序中的,M是指数据模型,V是指用户界面,C则是控制器。使用MVC的目的是将M和V的实现代码分离,从而使同一个程序可以使用不同的表现形式。比如一批统计数据你可以分别用柱状图、饼图来表示。C存在的目的则是确保M和V的同步,一旦M改变,V应该同步更新。

ASP.NET MVC模式图

ASP.NET MVC框架是既ASP.NET WebForms后的又一种开发方式。它提供了一系列优秀特性,使ASP.NET开发人员拥有了另一个选择。ASP.NET MVC框架选项非常干净,而且容易使用。它将允许你在应用中轻易地保持关注分离,且有助于进行干净的测试和TDD。

原文标题:Asp.net MVC2 使用经验,性能优化建议

链接:http://www.cnblogs.com/OtisBlog/archive/2010/03/22/1691676.html

【编辑推荐】

  1. 详解ASP.NET MVC 2中的Area特性
  2. 专访微软MVP衣明志:走进ASP.NET MVC 2框架开发
  3. 详解ASP.NET MVC 2中强类型HTML辅助方法
  4. 详解ASP.NET MVC 2自定义验证
  5. Scott Gu教你使用ASP.NET MVC 2新功能
责任编辑:彭凡 来源: 博客园
相关推荐

2009-07-24 13:20:44

MVC框架ASP.NET

2009-07-20 10:53:59

ASP.NET MVC

2009-07-22 10:09:59

ASP.NET MVC

2009-07-22 13:24:24

ASP.NET MVC

2009-07-22 13:08:55

拯救UpdatePanASP.NET MVC

2009-07-22 10:34:37

ActionInvokASP.NET MVC

2010-06-23 15:44:03

ASP.NET MVC

2009-09-14 15:04:44

2014-06-30 09:22:38

ASP.NETBootstrap

2009-03-13 10:58:48

ASP.NetMVC框架编程

2009-07-20 12:59:53

ASP.NET MVCASP.NET框架的功

2010-10-09 08:41:40

Mono 2.8

2009-07-31 12:43:59

ASP.NET MVC

2010-09-15 09:18:21

ASP.NET MVC

2009-07-20 15:51:40

FubuMVC核心框架ASP.NET MVC

2009-06-01 10:23:31

asp.net mvcasp.net mvc.net mvc框架

2009-07-24 10:55:00

asp.net mvc

2009-07-20 17:16:46

IIS中使用ASP.N

2009-10-28 13:35:25

VB.NET共享成员

2010-08-16 09:14:37

ASP.NET MVC
点赞
收藏

51CTO技术栈公众号