当前位置:必发365电子游戏 > 编程 > 从地点的代码中得以见见
从地点的代码中得以见见
2019-12-19

  在mvc的controller中,大家知晓有不菲的不时变量贮存数据,举例说viewData,viewBag,还大概有二个相比奇特的tempData,关于前三个大概大家都清楚,

大约是一个东西,正是个别的编制程序写法差异样,最后都会放到viewContext中,然后送到WebPage中,如若您要表明的话,能够看下上边包车型地铁代码。

        /// <summary>Gets the dynamic view data dictionary.</summary>
        /// <returns>The dynamic view data dictionary.</returns>
        [Dynamic]
        public dynamic ViewBag
        {
            [return: Dynamic]
            get
            {
                if (this._dynamicViewDataDictionary == null)
                {
                    this._dynamicViewDataDictionary = new DynamicViewDataDictionary(() => this.ViewData);
                }
                return this._dynamicViewDataDictionary;
            }
        }

        /// <summary>Gets or sets the dictionary for view data.</summary>
        /// <returns>The dictionary for the view data.</returns>
        public ViewDataDictionary ViewData
        {
            get
            {
                if (this._viewDataDictionary == null)
                {
                    this._viewDataDictionary = new ViewDataDictionary();
                }
                return this._viewDataDictionary;
            }
            set
            {
                this._viewDataDictionary = value;
            }
        }

从上边的代码中能够看来,其实ViewBag便是赢得ViewData的多寡,对不对。。。

 

一:TempData

    至于那几个事物怎么用,大家貌似都纪念是可访谈叁遍后即刻消失,好像平日也就这么了,当然不明了有没有人对tempdata的底层代码进行钻探吗???

看一下它的底层到底是怎么来落到实处的。

 

  1. TempData源代码

    首先大家看一下TempData的项目是TempDataDictionary,能够看出那个种类料定是落到实处了IDictionary接口的自定义字典,

        public TempDataDictionary TempData
        {
            get
            {
                if (this.ControllerContext != null && this.ControllerContext.IsChildAction)
                {
                    return this.ControllerContext.ParentActionViewContext.TempData;
                }
                if (this._tempDataDictionary == null)
                {
                    this._tempDataDictionary = new TempDataDictionary();
                }
                return this._tempDataDictionary;
            }
            set
            {
                this._tempDataDictionary = value;
            }
        }

从下面代码能够阅览,tempdate暗许是new了三个TempDataDictionary类,那么些类中很有意思的地点在于这里有贰个load方法,那几个load方法正是收获真

正的provider,比方上面那样:

        /// <summary>Loads the specified controller context by using the specified data provider.</summary>
        /// <param name="controllerContext">The controller context.</param>
        /// <param name="tempDataProvider">The temporary data provider.</param>
        public void Load(ControllerContext controllerContext, ITempDataProvider tempDataProvider)
        {
            IDictionary<string, object> dictionary = tempDataProvider.LoadTempData(controllerContext);
            this._data = ((dictionary != null) ? new Dictionary<string, object>(dictionary, StringComparer.OrdinalIgnoreCase) : new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase));
            this._initialKeys = new HashSet<string>(this._data.Keys, StringComparer.OrdinalIgnoreCase);
            this._retainedKeys.Clear();
        }

必发娱乐365登录,其生龙活虎load方法正是特别重大的,这里的参数ITempDataProvider正是我们在BeginExecute方法赋值的,继续往下看,不要忧虑啊。。。

 

必发365手机版ww,2. BeginExecute

   大家理解,mvc框架其实是收缴了mvcroutehandler来扩充收缴url的伏乞,进而将继续的拍卖就由mvc框架来接管,最后会实践到Controller类上边包车型地铁

BeginExecute,就算您不相信,作者得以欢腾加喜悦的给你上代码,举例下边那样:

        protected virtual IAsyncResult BeginExecute(RequestContext requestContext, AsyncCallback callback, object state)
        {
            Action action2 = null;
            if (this.DisableAsyncSupport)
            {
                if (action2 == null)
                {
                    action2 = delegate {
                        this.Execute(requestContext);
                    };
                }
                Action action = action2;
                return AsyncResultWrapper.BeginSynchronous(callback, state, action, _executeTag);
            }
            if (requestContext == null)
            {
                throw new ArgumentNullException("requestContext");
            }
            base.VerifyExecuteCalledOnce();
            this.Initialize(requestContext);
            BeginInvokeDelegate<Controller> beginDelegate = (asyncCallback, callbackState, controller) => controller.BeginExecuteCore(asyncCallback, callbackState);
            EndInvokeVoidDelegate<Controller> endDelegate = delegate (IAsyncResult asyncResult, Controller controller) {
                controller.EndExecuteCore(asyncResult);
            };
            return AsyncResultWrapper.Begin<Controller>(callback, state, beginDelegate, endDelegate, this, _executeTag, -1, null);
        }

上边这段代码中,你肯定要看了解上边标红的地点,这里我们看出了,其实这里是叁个异步的beginxxx,endxxx的操作,难点正是在那处,首先大家从

beginInvoke说起。

 

<1> beginDelegate

       那么些异步操作中,大家得以看出,其实推行的是叁个controller.BeginExecuteCore(asyncCallback, callbackState) 方法,对吧,然后我们得以

感兴趣的看一下那些办法干了怎么着?

        protected virtual IAsyncResult BeginExecuteCore(AsyncCallback callback, object state)
        {
            IAsyncResult result;
            this.PossiblyLoadTempData();
            try
            {
                Action action2 = null;
                string actionName = GetActionName(this.RouteData);
                IActionInvoker invoker = this.ActionInvoker;
                IAsyncActionInvoker invoker = invoker as IAsyncActionInvoker;
                if (invoker != null)
                {
                    BeginInvokeDelegate<ExecuteCoreState> beginDelegate = (asyncCallback, asyncState, innerState) => innerState.AsyncInvoker.BeginInvokeAction(innerState.Controller.ControllerContext, innerState.ActionName, asyncCallback, asyncState);
                    EndInvokeVoidDelegate<ExecuteCoreState> endDelegate = delegate (IAsyncResult asyncResult, ExecuteCoreState innerState) {
                        if (!innerState.AsyncInvoker.EndInvokeAction(asyncResult))
                        {
                            innerState.Controller.HandleUnknownAction(innerState.ActionName);
                        }
                    };
                    ExecuteCoreState invokeState = new ExecuteCoreState {
                        Controller = this,
                        AsyncInvoker = invoker,
                        ActionName = actionName
                    };
                    return AsyncResultWrapper.Begin<ExecuteCoreState>(callback, state, beginDelegate, endDelegate, invokeState, _executeCoreTag, -1, null);
                }
                if (action2 == null)
                {
                    action2 = delegate {
                        if (!invoker.InvokeAction(this.ControllerContext, actionName))
                        {
                            this.HandleUnknownAction(actionName);
                        }
                    };
                }
                Action action = action2;
                result = AsyncResultWrapper.BeginSynchronous(callback, state, action, _executeCoreTag);
            }
            catch
            {
                this.PossiblySaveTempData();
                throw;
            }
            return result;
        }

从上边包车型大巴代码中,你应当看见了有一个 this.PossiblyLoadTempData(卡塔尔方法,看那些名字大家大约就足以猜获得这一个法子和tempdate料定有惊人的关系。

说时迟那时候快,大家能够看下那么些艺术到底干了什么样。。。在风度翩翩层层追踪之后,大家最后会到这一个代码里面去了,如下所示:

        internal void PossiblyLoadTempData()
        {
            if (!base.ControllerContext.IsChildAction)
            {
                base.TempData.Load(base.ControllerContext, this.TempDataProvider);
            }
        }

 

请大家看清了,这里大家调用了刚刚小说早前出说起的Tempdata.Load方法,那么难题来了,这里的TempDataProvider到底是怎么来的。我们继续来看代码:

        public ITempDataProvider TempDataProvider
        {
            get
            {
                if (this._tempDataProvider == null)
                {
                    this._tempDataProvider = this.CreateTempDataProvider();
                }
                return this._tempDataProvider;
            }
            set
            {
                this._tempDataProvider = value;
            }
        }

 

看看未有,然后TempDataProvider然来是调用了CreateTempDataProvider方法来兑现的,下一步我们来看一下CreateTempDataProvider到底干了怎么。

        protected virtual ITempDataProvider CreateTempDataProvider()
        {
            ITempDataProviderFactory service = this.Resolver.GetService<ITempDataProviderFactory>();
            if (service != null)
            {
                return service.CreateInstance();
            }
            return (this.Resolver.GetService<ITempDataProvider>() ?? new SessionStateTempDataProvider());
        }

从地点这些代码,大家相应就明白了,然来大家的tempdata暗中同意是由SessionStateTempDataProvider来提供的,好了,接下去大家就可以继续看看

SessionStateTempDataProvider大致实现的事情逻辑。

  public class SessionStateTempDataProvider : ITempDataProvider
    {
        internal const string TempDataSessionStateKey = "__ControllerTempData";

        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);
        }

        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");
            }
        }
    }

能够观望,SessionStateTempDataProvider 是落到实处了ITempDataProvider接口,里面有五个艺术LoadTempData 和SaveTempData方法,而

LoadTempData方法的逻辑很奇葩,你能够留神观察一下哦,假诺 if (session != null卡塔尔(قطر‎满足就清空字典的多少,否则就不消弭,这么些逻辑差少之甚少就向

您出示了怎么数据只好被读取叁遍,后一次读取的时候,就走了这些if(session!=null卡塔尔给清空了,你怎么大概再读取session中的数据吧。。。那个

就算怎么tempdata只好被读取三回的精气神,是或不是很有趣。

 

<2> EndExecuteCore

从地点的代码中得以见见。    有人只怕会问了,第3个艺术SaveTempData是什么样时候实践的,当然就是EndExecuteCore里面了,比方您看:

        protected virtual void EndExecuteCore(IAsyncResult asyncResult)
        {
            try
            {
                AsyncResultWrapper.End(asyncResult, _executeCoreTag);
            }
            finally
            {
                this.PossiblySaveTempData();
            }
        }

可以观望它的暗中同意完成是session,当然你也足以完成二个自定义的provider,举例用cache来存放在此个有的时候数据,恐怕是redis,mongodb等等。。。

自然还应该有更加多遗闻物等待你打通哦~~~

 

上一篇:没有了