asp.net mvc(四)

來源:互聯網
上載者:User

     我在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<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);
    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<string, object> LoadTempData(ControllerContext controllerContext)
{
    HttpContextBase httpContext = controllerContext.HttpContext;
    if (httpContext.Session == null)
    {
        throw new InvalidOperationException(MvcResources.SessionStateTempDataProvider_SessionStateDisabled);
    }
    Dictionary<string, object> dictionary = httpContext.Session["__ControllerTempData"] as Dictionary<string, 

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

public virtual void SaveTempData(ControllerContext controllerContext, IDictionary<string, object> 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
 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.