今天在ASP.NET MVC代码时用到了Html.RenderAction,代码如下:

@{Html.RenderAction("RecentNews")}

通过字符串指定Action的名称,有两点不爽:

1. 输入时不能智能感知;

2. 输错了不能实时提示。

有这两点不爽,写代码的乐趣就大减。有享受感觉的代码应该是这样的:

@{Html.RenderAction<AggSiteController>(c => c.RecentNews());}

是的,Lamda,给你写代码带来畅快感觉的Lamda!

微软不让我们享受,我们就自己动手,丰衣足食。自己写一个支持Lamda表达式的Html.RenderAction,代码如下:

using System.Web.Mvc;
using System.Web.Mvc.Html;
using System.Linq.Expressions;namespace System.Web.Mvc.Html
{public static class HtmlHelperExtensions{public static void RenderAction<TController>(this HtmlHelper htmlHelper, Expression<Action<TController>> operation) where TController : Controller{var actionName = ((MethodCallExpression)operation.Body).Method.Name;htmlHelper.RenderAction(actionName);}}
}

注:其中"((MethodCallExpression)operation.Body).Method.Name"代码来自Get Method Name From Action。

顺带分享一篇文章When to use Html.RenderPartial and Html.RenderAction in ASP.NET MVC Razor Views,通过这篇文章你可以清楚的知道Html.RenderPartial与Html.RenderAction之间的区别。

比如:博客园首页的最新随笔列表就适合用Html.RenderPartial,而右侧的“新闻列表”就适合用Html.RenderAction。

简单的理解就是:Html.RenderPartial用的到PartialView只用一次(虽然实际可以多次使用,但比较麻烦,每次都要传Model),Html.RenderAction用的到PartialView被多个视图使用(有自己的Action提供Model)。

在评论中,向晚提到了Html.RenderAction的一个优点:

ChildAciton的优势是可以应用OutputCahce特性实现局部缓存。

我们当时用Html.RenderAction,而不用Html.RenderPartial,这也是一个重要原因。

总结一下ChildAciton+PartialView的优势:

  1. 可以在“不同Action相同View”中方便地被共享
  2. 可以在“不同Action不同View”中方便地被共享
  3. “可以应用OutputCahce特性实现局部缓存”

我们在解决另外一个问题时,发现它还有一个优势:

  4. 可以用ChildAciton直接处理Ajax请求。

比如博客园首页加载“最新随笔列表”的应用场景,在用户打开页面时直接显示最新随笔(非ajax加载);在用户点击页面上的“刷新”链接时,通过ajax更新“最新随笔列表”。

使用ChildAciton+PartialView,在首页页面视图中只需Html.RenderAction即可。

@{ Html.RenderAction<AggSiteController>(c => c.PostList(1,20)); }

同样的ChildAction可以直接服务于Ajax请求,实现了ChildAciton+PartialView的重用。

这时,我们遇到了一个问题,在RenderAction的时候需要向Action传递参数,之前实现的简陋的Html.RenderAction并没有对此提供支持,需要改进一下。

从testzhangsan的评论中获知,ASP.NET MVC 4中已经在实现Lamda版Html.RenderAction。签出ASP.NET MVC 4的源代码一下,果然实现了,向Action传参数的问题自然也被微软解决了。参照那段代码,精简一下就能解决我们的问题。

向Action传参数,需要通过RouteValueDictionary,我们所要做的工作就是从Lamda表达式中获取参数名称与参数值,并还添加至RouteValueDictionary。

完整代码如下:

using System.Web.Mvc;
using System.Web.Mvc.Html;
using System.Linq.Expressions;
using System.Web.Routing;namespace System.Web.Mvc.Html
{public static class HtmlHelperExtensions{public static void RenderAction<TController>(this HtmlHelper htmlHelper,Expression<Action<TController>> operation)where TController : Controller{var controllerName = typeof(TController).Name;if (controllerName.EndsWith("Controller")){controllerName = controllerName.Substring(0, controllerName.Length - "Controller".Length);}var call = operation.Body as MethodCallExpression;if (call != null){var actionName = call.Method.Name;var parameters = call.Method.GetParameters();if (parameters.Length > 0){var routeValues = new RouteValueDictionary();for (int i = 0; i < parameters.Length; i++){var ce = call.Arguments[i] as ConstantExpression;if (ce != null){routeValues.Add(parameters[i].Name, ce.Value);}else{var lambda = Expression.Lambda(call.Arguments[i],operation.Parameters);Delegate d = lambda.Compile();var value = d.DynamicInvoke(new object[1]);routeValues.Add(parameters[i].Name, value);}}htmlHelper.RenderAction(actionName, controllerName, routeValues);}else{htmlHelper.RenderAction(actionName, controllerName);}}}}
}

注:目前的这个实现不支持可空类型的参数,比如:public ActionResult PostList(int? pageIndex)。

开源,真好!

转载于:https://www.cnblogs.com/majiang/articles/2736629.html

[ASP.NET MVC]让Html.RenderAction支持Lamda表达式相关推荐

  1. 【邹健】Asp.net MVC Fckeditor的扩展(支持PV3及自动绑定)

    Asp.net MVC Fckeditor的扩展(支持PV3及自动绑定) function StorePage(){d=document;t=d.selection?(d.selection.type ...

  2. 为了去重复,写了一个通用的比较容器类,可以用在需要比较的地方,且支持Lamda表达式...

    为了去重复,写了一个通用的比较容器类,可以用在需要比较的地方,且支持Lamda表达式,代码如下: public class DataComparer<T>:IEqualityCompare ...

  3. ASP.NET MVC:多模板支持

    背景 准备写个博客练习一下WEB编程,有一个需求就是多模板支持,类似博客园的自定义模板一样,在ASP.NET MVC中如何处理这个需求呢? 需求 描述 允许自定义模板,比如:传统模板.Metro模板等 ...

  4. 一起谈.NET技术,专访微软MVP衣明志:走进ASP.NET MVC 2框架开发

    日前微软已经发布ASP.NET MVC 2框架RC版,究竟这次RC版本的发布对于WEB开发者带来怎样的改变?以及未来ASP.NET MVC 2正式版还会有哪些改进?带着这样的问题,我们51CTO记者彭 ...

  5. ASP.NET MVC Framework 系列

    序言 做为设计模式的王者,MVC在众多领域都成为良好的模型的代名词,从前在ASP.NET下我们只能依靠Monorail来实现ASP.NET下无控件的MVC,但是现在ASP.NET 下的MVC已经成为现 ...

  6. 一起谈.NET技术,在Mono 2.8上部署ASP.NET MVC 2

    我们知道Mono 2.8对ASP.NET MVC 2的完全支持,下面我们就来测试下在Mono 2.8上部署ASP.NET MVC 2应用程序.我的环境是Opensuse 11.3,通过以下命令部署好M ...

  7. SharpDeveloeper开发ASP.NET MVC汗流浃背

    今天好不容易休息了一天,上网狂了一圈,突然想起了以前的一个轻量级的开发工具"SharpDeveloper",于是就下载试着来开发一下ASP.NET,但是老魏没有想到的是,虽然官方提 ...

  8. 写在《ASP.NET MVC 4 Web 编程》即将出版之际!献给有节操的程序员!

    <Programming ASP.NET MVC 4>中文版即将上市了!非常荣幸我可以再次参与一本不错的技术书籍的翻译工作. 这也是在<WCF技术内幕>与<WCF服务编程 ...

  9. ASP.NET MVC 重点教程一周年版 第七回 UrlHelper 【转】

    这节讲 一下ASP.NET MVC中的Helper. 何谓Helper,其实就是在View中为了实现一些灵活功能而写的方法组. 其实ASP.NET MVC的View是Aspx的页面,本身可以声明定义方 ...

最新文章

  1. Leetcode刷题 225题:用队列实现栈(基于Java和c++两种语言)
  2. 解读高效的神经架构搜索ENAS
  3. 会议报到和撒离时间算会期_【明日报到】2020中国(三门峡)食用菌新产品新技术博览会工作人员开始分装资料...
  4. 自动关机脚本2007-10-28 10:04@ECHO off
  5. composer 笔记
  6. android开发学习-日经常使用到的好东西-经常使用技巧分享
  7. Linux 查看日志的方法
  8. ## Python笔记
  9. 淘宝天猫商家运营,宝贝标题如何突出卖点,标题编写方法小技巧
  10. 想减肥就要管住嘴,怎么管?这个方法可以
  11. gcc编译工具常用命令以及汇编语言
  12. golang调用网易云API
  13. u盘 linux 装系统 suse,从u盘启动安装opensuse 11.4 livecd
  14. Linuxshell脚本之循环语句
  15. 精通计算机英语,学好英语有助于精通电脑
  16. 爆款小游戏用的都是什么游戏开发引擎?
  17. MFC openGL立方体
  18. 全开源微信现场大屏幕小程序源码V1.7.6
  19. JQuery简单实用的模板引擎
  20. 多元函数的极值和鞍点

热门文章

  1. 【Flink】SASL encryption trust check: localHostTrusted = false, remoteHostT
  2. 【Flink】Flink 写入 Clickhouse 大对象直接进入老年代 导致OOM
  3. 【Elasticsearch】 海量 分词器 在线地址 与文档
  4. 40-400-030-运维-优化-MySQL入门调优脚本tuning-primer的使用
  5. 【Es】es 无法启动 报错 Elasticsearch.init Bootstrap.setup OsProbe NullPointException
  6. 【antlr】antlr语法中的fragment
  7. 【高并发】JUC中的循环栅栏CyclicBarrier的6种使用场景
  8. VM : linux虚拟机上挂在U盘
  9. 95-110-040-源码-Env-StreamTableEnvironment
  10. 集合WeakHashMap