原文链接:http://www.dotnetbips.com/articles/bc422c95-02cc-4d05-9c5c-fa89d0e78cc0.aspx
1.前言
本来今天是想发那篇关于在Web API中关于路由的选择,但那一份是在公司翻译的,文件也在公司里。然后自己也比较感兴趣一些比较偏的知识。就像今天这一篇。在翻译的过程中,很多的文字自己感觉到十分的生硬,希望以后在自己看懂文章后,用文字将自己的理解表达出来,相信这样会更好。
2. 开始
在MVC中,相信大家都使用过ViewData或ViewBag(ViewBag是ViewData的一层封装),还一个用于在控制器向视图传递数据的方法-TempData,那我们能不能使用类似ViewBag包装ViewData的方式,使用TempBag实现动态查找值。我们可以创建一个类,如下
1 public class TempBag: DynamicObject
2 {
3 TempDataDictionary tempData = null;
4
5 public TempBag(TempDataDictionary tempdata)
6 {
7 this.tempData = tempdata;
8 }
9
10 public override bool TryGetMember(GetMemberBinder binder, out object result)
11 {
12 try
13 {
14 //如果能找到相应的Key
15 if (tempData.Keys.Where(k => k == binder.Name).Count() > 0)
16 {
17 result = tempData[binder.Name];
18 return true;
19 }
20 else
21 {
22 result = "找不到值";
23 return false;
24 }
25 }
26 catch
27 {
28 result = "找不到值";
29 return false;
30 }
31 }
32
33 public override bool TrySetMember(SetMemberBinder binder, object value)
34 {
35 try
36 {
37 tempData[binder.Name] = value;
38 return true;
39 }
40 catch
41 {
42 return false;
43 }
44 }
45 }
DynamicObject类位于System.Web.Mvc下,使用DynamicObject能够创建自己的动态对象。自己的类需要继承DynamicObject类,重写里面的三个方法:TrySetMember、TryGetMember、TryInvokeMember,前面两个方法用于设置和获取属性的实现,最后一个方法用于动态方法的调用,这里就不作介绍。
3.控制器中代码
1 public class TempDataController : Controller
2 {
3
4 dynamic tempBag = null;
5
6 public TempDataController()
7 {
8 tempBag = new TempBag(TempData);
9 }
10
11 public ActionResult Index()
12 {
13 tempBag.Message = "一个很好的结果";
14 return View();
15 }
16
17 }
在实例化控制器的时候,将它的一个动态对象实例化为我们自己定义的类的类型。控制器的构造函数中,传递TempData作为参数,那么我们在自己类中重写的两个方法分别对应为TempData设置和获取值。
4.在视图面的代码
1 @{
2 Layout = null;
3 dynamic tempBag = new TempBag(TempData);
4 }
5
6 <!DOCTYPE html>
7
8 <html>
9 <head>
10 <meta name="viewport" content="width=device-width" />
11 <title>Index</title>
12 </head>
13 <body>
14 <div>
15 <p>@@tempBag.Message的值为: @tempBag.Message</p>
16 <p>@@TempData["Message"]的值为: @TempData["Message"]</p>
17 </div>
18 </body>
19 </html>
如果没差错,那显示的结果如下图
在视图页面,也需要创建一个TempBag的对象,这样才能访问到TempData对象。我们也能看到,使用@TempData["Message"]也能访问到我们定义的值,从这一侧面也表示,我们也只是为了动态访问TempData创建自己的类TempBag,就好像ViewBag之于ViewData。