js怎么获取mvc3的model或者viewdata

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了js怎么获取mvc3的model或者viewdata相关的知识,希望对你有一定的参考价值。

参考技术A js只能获取页面上的html元素或AJAX返回的结果.~

如果你想要用js去获取MVC中的model或viewdata的话.
那么你必须要用方法去使得model或viewdata转换为JS能获取的对象
例如:
HTML中的<input id="x" type="hidden" value='<%: ViewData["x"].ToString() %>' />
//或许你能有更好的生成HTML标记的方法,在此我仅仅是做个示范.
然后在jQuery中
var x = $("#x").val();本回答被提问者和网友采纳

MVC源码解读ViewDataViewBagTempData的区别

asp.net MVC框架提供了4种控制器向视图传值的方法:分别是ViewData,ViewBag,TempData,Model(Model暂不讨论,因为也没啥说的)


平时使用的过程中虽然了解了差异但是不知其所以然,所以这两天用反编译器看了源码,算是知道了个大概。


ViewData和ViewBag


这两货为什么要放在一起来说呢?因为这两个其实底层的实现都是ViewData。ViewBag是对ViewData的封装,牺牲了性能换来了更好的可读性。而且由于ViewBag是dynamic类型,所以使用的时候不需要进行类型转换。

//ControllerBase类里面的ViewBag属性public dynamic ViewBag{ get { if (_dynamicViewDataDictionary == null) {        //重点看这句代码 _dynamicViewDataDictionary = new DynamicViewDataDictionary(() => ViewData); } return _dynamicViewDataDictionary; }}
private DynamicViewDataDictionary _dynamicViewDataDictionary;
可以看到ViewBag的本质就是一个DynamicViewDataDictionary类型,而且在构造函数里面传入了一个委托。我们来看看DynamicViewDataDictionary这个类
internal sealed class DynamicViewDataDictionary : DynamicObject{  //私有委托字段,返回值是一个ViewDataDictionary类型 private readonly Func<ViewDataDictionary> _viewDataThunk; //调用委托函数将返回值赋予给ViewData字段 private ViewDataDictionary ViewData => _viewDataThunk();   //DynamicViewDataDictionary的构造函数,需要传入一个委托。 public DynamicViewDataDictionary(Func<ViewDataDictionary> viewDataThunk) { _viewDataThunk = viewDataThunk; }    //下面3个方法都是通过ViewData属性来进行操作的   public override IEnumerable<string> GetDynamicMemberNames() { return ViewData.Keys; }
public override bool TryGetMember(GetMemberBinder binder, out object result) { result = ViewData[binder.Name]; return true; }
public override bool TrySetMember(SetMemberBinder binder, object value) { ViewData[binder.Name] = value; return true; }}


结论:

ViewBag对数据存储的本质是其底层封装了一个ViewDataDictionary对象。关键是这个ViewDataDictionary对象就是ViewData。



TempData


TempData的数据是存储在session里面的,所以可以跨控制器传值。但是有个特点:存储的数据使用一次之后就会被删除。

/// <summary>Invokes the action in the current controller context.</summary>protected override void ExecuteCore(){ PossiblyLoadTempData(); //注意这里 try { string actionName = GetActionName(RouteData); if (!ActionInvoker.InvokeAction(base.ControllerContext, actionName)) { HandleUnknownAction(actionName); } } finally { PossiblySaveTempData(); }}
internal void PossiblyLoadTempData(){ if (!base.ControllerContext.IsChildAction) { base.TempData.Load(base.ControllerContext, TempDataProvider); }}

可以看到,在调用action方法之前先调用了PossiblyLoadTempData(),调用完action之后又调用了PossiblySaveTempData()。


先来研究PossiblyLoadTempData(),这个方法又调用了TempData.Load。

看一下Load方法

public void Load(ControllerContext controllerContext, ITempDataProvider tempDataProvider){ IDictionary<string, object> dictionary = tempDataProvider.LoadTempData(controllerContext); _data = ((dictionary != null) ? new Dictionary<string, object>(dictionary, StringComparer.OrdinalIgnoreCase) : new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase)); _initialKeys = new HashSet<string>(_data.Keys, StringComparer.OrdinalIgnoreCase); _retainedKeys.Clear();}

看一下LoadTempData

public virtual IDictionary<string, object> LoadTempData(ControllerContext controllerContext){ HttpSessionStateBase session = controllerContext.HttpContext.Session; if (session != null) { Dictionary<string, object> dictionary = session["__ControllerTempData"] as Dictionary<string, object>; if (dictionary != null) { session.Remove("__ControllerTempData"); return dictionary; } } return new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);}

可以看到LoadTempData到session里面取完数据保存到字典返回之后就把session的数据清空了。

字典返回的数据存到了TempData的_data字段里面。同时将字典的所有key值存到了_initialKeys 字段里面并且清空_retainedKeys字段。


看一下TempDataDictionary

public class TempDataDictionary : IDictionary<string, object>, ICollection<KeyValuePair<string, object>>, IEnumerable<KeyValuePair<string, object>>, IEnumerable{ public object this[string key] { get { if (TryGetValue(key, out object value)) { _initialKeys.Remove(key); return value; } return null; } set { _data[key] = value; _initialKeys.Add(key); } }}

字典每次取完值之后,就会在_initialKeys将该值的key移除掉(TempData的特性就是取完值就删了,此处有伏笔)


再来看PossiblySaveTempData(),直接贴代码了

internal void PossiblySaveTempData(){ if (!base.ControllerContext.IsChildAction) { base.TempData.Save(base.ControllerContext, TempDataProvider); }}//看一下Save方法public void Save(ControllerContext controllerContext, ITempDataProvider tempDataProvider){ _data.RemoveFromDictionary(delegate(KeyValuePair<string, object> entry, TempDataDictionary tempData) { string key = entry.Key; return !tempData._initialKeys.Contains(key) && !tempData._retainedKeys.Contains(key); }, this); tempDataProvider.SaveTempData(controllerContext, _data);}
//看一下RemoveFromDictionary方法public static void RemoveFromDictionary<TKey, TValue, TState>(this IDictionary<TKey, TValue> dictionary, Func<KeyValuePair<TKey, TValue>, TState, bool> removeCondition, TState state){ int num = 0; TKey[] array = new TKey[dictionary.Count]; foreach (KeyValuePair<TKey, TValue> item in dictionary) { if (removeCondition(item, state)) { array[num] = item.Key; num++; } } for (int i = 0; i < num; i++) { dictionary.Remove(array[i]); }}

如果_initialKeys_retainedKeys里面都不包含某个key时,那么这个key就会在字典里面被删除。

public virtual void SaveTempData(ControllerContext controllerContext, IDictionary<string, object> values){ if (controllerContext == null) { throw new ArgumentNullException("controllerContext"); } HttpSessionStateBase session = controllerContext.HttpContext.Session; bool flag = values != null && values.Count > 0; if (session == null) { if (flag) { throw new InvalidOperationException(MvcResources.SessionStateTempDataProvider_SessionStateDisabled); } } else if (flag) { session["__ControllerTempData"] = values; } else if (session["__ControllerTempData"] != null) { session.Remove("__ControllerTempData"); }}

然后将字典的值保存到session里面。


结论:ExecuteCore执行,在调用action方法之前,先到session里面去取数据存到Tempdata里面(同时将所有的key值存到_initialKeys)然后清空session数据。当我们从Tempdata取值时,该值的key便会在_initialKeys里面移除。调用完action方法之后遍历Tempdata的key值,如果key既不在_initialKeys也不在_retainedKeys,则会将该key值的键值对从Tempdata移除(这就是TempData数据只有一次性的原因)。之后再将Tempdata的数据存回session。


如果我们想重复使用TempData的数据,只需要将key添加到_initialKeys或者_retainedKeys里面即可。


TempDataDictionary类提供了Keep方法

 public void Keep(string key) { _retainedKeys.Add(key); }


以上是关于js怎么获取mvc3的model或者viewdata的主要内容,如果未能解决你的问题,请参考以下文章

MVC3:通过Javascript获取下拉菜单选择的值/文本

MVC3 Html.HiddenFor(Model => Model.Id) 不传回控制器

thymeleaf 怎么使用js获取model

如何在html页面使用js获取model里的值

js怎样获得后台Model中的值?

js怎样获得后台Model中的值