我查了相关质料也看了源码 大致得到的结论是 没有办法动态的赋值 至于遍历 我还没开始处理!
需求是 我期望用一段代码插入到 action中 动态的处理一些符合规律的请求值
将其仿佛viewbag
然后通过遍历 取回这些值
最终做到 传值的过程不用手动介入
请问有人处理过这类问题么?
我想先占位子,事后想想
听说这里有个50豆的问题,然后百度一下,第一条:http://q.cnblogs.com/q/74582/
这个不是遍历
@小眼睛老鼠: foreach不是遍历?
@小光: 我要遍历的是 viewbag的属性
遍历viewbag里面有没有dataBuySum
而你这个例子遍历的是 dataBuySum
@小眼睛老鼠: 好吧。。。
ViewBag是对ViewData的包装,遍历的方式:
1.对ViewData遍历
2.反射ViewBag,对ViewData遍历
var viewDataProperty = ViewBag.GetType() .GetProperty("ViewData", BindingFlags.NonPublic | BindingFlags.Instance); var viewData = viewDataProperty.GetValue(ViewBag); foreach (var pair in viewData) { Console.WriteLine("{0}-{1}", pair.Key, pair.Value); }
3.利用动态特性
public static object GetProperty(object o, string name) { if (o == null) throw new ArgumentNullException("o"); if (name == null) throw new ArgumentNullException("name"); var type = o.GetType(); var provider = o as IDynamicMetaObjectProvider; if (provider != null) { var prop = Expression.Parameter(typeof(object)); var dmo = provider.GetMetaObject(prop); var gmb = (GetMemberBinder) Microsoft.CSharp.RuntimeBinder.Binder.GetMember(CSharpBinderFlags.None, name, type, new CSharpArgumentInfo[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) }); var result = dmo.BindGetMember(gmb); var final = Expression.Block( Expression.Label(CallSiteBinder.UpdateLabel), result.Expression); var lambda = Expression.Lambda(final, prop); var d = lambda.Compile(); return d.DynamicInvoke(o); } else { return o.GetType().GetProperty(name, BindingFlags.Public | BindingFlags.Instance).GetValue(o, null); } }
使用方式:
var keys = ViewBag.GetDynamicMemberNames(); foreach (var key in keys) { var value = GetProperty(ViewBag, key); }
关于动态赋值:
public static void SetProperty(object o, string name, object value) { if (o == null) throw new ArgumentNullException("o"); if (name == null) throw new ArgumentNullException("name"); var type = o.GetType(); var provider = o as IDynamicMetaObjectProvider; if (provider != null) { var propName = Expression.Parameter(typeof(object)); var gmb = (SetMemberBinder) Microsoft.CSharp.RuntimeBinder.Binder.SetMember(CSharpBinderFlags.None, name, type, new CSharpArgumentInfo[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null), CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) }); var callSite = CallSite<Func<CallSite, object, object, object>>.Create(gmb); callSite.Target(callSite, o, value); } else { o.GetType().GetProperty(name, BindingFlags.Public | BindingFlags.Instance).SetValue(o, value); } }
使用方式:
SetProperty(ViewBag, "Music", "JiangNan Style");
谢谢了 :) 我回去调试下 ok了就给分