zoukankan      html  css  js  c++  java
  • asp.net mvc(四)

         我在asp.net mvc (三) 中有类似如下的问题:有一个Partial View控件,在home这个view中使用该控件,怎么取key和value??就是在Partial View控件如何向View传值。

         我当时说到ViewData的应用,但ViewData 局限于当前Action。现在有了TempData后,一切都解决了。

         解决方案:修改生成留言的Action:这里给一个TempData赋值。

    [AcceptVerbs(HttpVerbs.Post)]
           
    public ActionResult Create(GuestBookInfo model)
           {
               
    try
               {
                   inter.Add(model);
                   var  models 
    = inter.FindAllInfo();
                   TempData[
    "TempData"= "已经成功创建";
                   
    return RedirectToAction("Index");
               }
               
    catch(Exception ex)
               {
                   ModelState.AddModelError(
    "ex",ex);
                   
    return View(model);

               }
           }  

     

            然后在index View 就可以方便的访问下面的值:<%=TempData["TempData"]%>,有趣的是当TempData["TempData"]没有赋值时,这条语句并不会出错。


            我们来看下Controller之间为什么可以通过TempData来实现传值,在传统的asp.net 中我们经常会利用Session或者是Cookie来传值,TempData因为并不是通过网页参数传值,所以肯定是把数据存储在某个地方的原因。

            第一:查看Controller类的源码,其中包含一个重要的方法:在这个方面开始前就调用了基类的TempData.Load方法。

    protected override  void ExecuteCore()
    {
        
    base.TempData.Load(base.ControllerContext, this.TempDataProvider);
        
    try
        {
            
    string requiredString = this.RouteData.GetRequiredString("action");
            
    if (!this.ActionInvoker.InvokeAction(base.ControllerContext, requiredString))
            {
                
    this.HandleUnknownAction(requiredString);
            }
        }
        
    finally
        {
            
    base.TempData.Save(base.ControllerContext, this.TempDataProvider);
        }
    }

      
           第二:TempData.Load方法:可以看到最终是由ITempDataProvider这个接口来完成。

    public void Load(ControllerContext controllerContext, ITempDataProvider tempDataProvider)
    {
        IDictionary
    <stringobject> dictionary = tempDataProvider.LoadTempData(controllerContext);
        
    this._data = (dictionary != null? new Dictionary<stringobject>(dictionary, 

    StringComparer.OrdinalIgnoreCase) : 
    new Dictionary<stringobject>(StringComparer.OrdinalIgnoreCase);
        
    this._initialKeys = new HashSet<string>(this._data.Keys);
        
    this._modifiedKeys.Clear();
    }

       
          第三:ITempDataProvider:我们可以在第一条中的代码中发现,接口是这样取的:

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


            第四:SessionStateTempDataProvider,从这个名字我们就可以猜测,数据应该是用Session方式保存。主要包含了两个方法,分别用于加载数据和保存数据。

    public virtual IDictionary<stringobject> LoadTempData(ControllerContext controllerContext)
    {
        HttpContextBase httpContext 
    = controllerContext.HttpContext;
        
    if (httpContext.Session == null)
        {
            
    throw new InvalidOperationException(MvcResources.SessionStateTempDataProvider_SessionStateDisabled);
        }
        Dictionary
    <stringobject> dictionary = httpContext.Session["__ControllerTempData"as Dictionary<string

    object>;
        
    if (dictionary != null)
        {
            httpContext.Session.Remove(
    "__ControllerTempData");
            
    return dictionary;
        }
        
    return new Dictionary<stringobject>(StringComparer.OrdinalIgnoreCase);
    }

    public virtual void SaveTempData(ControllerContext controllerContext, IDictionary<stringobject> values)
    {
        HttpContextBase httpContext 
    = controllerContext.HttpContext;
        
    if (httpContext.Session == null)
        {
            
    throw new InvalidOperationException(MvcResources.SessionStateTempDataProvider_SessionStateDisabled);
        }
        httpContext.Session[
    "__ControllerTempData"= values;
    }

      
          小结:TempData虽然用Session来实现数据的存储,但对服务器来讲,代价虽然有,但并不高,因为从代码上看TempData用完一次就会被消除掉。看到这,我们可以想,是否可以看定义一个TempDataProvider,当然可以。这里我创建一个示例,并没有做功能上的改变,可以根据实际情况修改:

          1:创建MyTempDataProvider,让它继承ITempDataProvider ,并且实现LoadTempData和SaveTempData。
     
          2:将MyTempDataProvider与Controller联系上,我们可以选择扩展默认控制器工厂(DefaultControllerFactory) ,重写IController CreateController方法:

    public override IController CreateController(RequestContext requestContext, string controllerName)
            {
                Controller controller 
    = base.CreateController(requestContext, controllerName) as Controller ;
                
    if (null != controller)
                {
                    controller.TempDataProvider 
    = new MyTempDataProvider();
                }
                
    return controller;

            }

       
           3:注册我们自定义的MyControllerFactory,这也是最后一步。

    protected void Application_Start()
            {
                ControllerBuilder.Current.DefaultNamespaces.Add(
    "GuestBook.MVC.Controller");
                ModelBinders.Binders.Add(
    typeof(GuestBookInfo ), new GuestBookBinder ());
                ControllerBuilder.Current.SetControllerFactory(
    typeof(MyControllerFactory ));
                RegisterRoutes(RouteTable.Routes);
            }


            总结:通过了解TempData的实现机制以及生命周期,我们就不难实现我之前的难题了。

            注:本文参考:http://www.cnblogs.com/tristanguo/archive/2009/04/12/1433462.html
     

  • 相关阅读:
    896. 单调数列
    819. 最常见的单词
    collections.Counter()
    257. 二叉树的所有路径
    万里长征,始于足下——菜鸟程序员的学习总结(三)
    Ogre启动过程&原理
    Ogre导入模型
    四元数
    Ogre3D嵌入Qt框架
    如何搭建本地SVN服务
  • 原文地址:https://www.cnblogs.com/ASPNET2008/p/1543843.html
Copyright © 2011-2022 走看看