ASP.NET MVC3 向View传递数据

我们可以通过ViewResult 使Action传递数据到View.

一般来说我们使用3种方式通过Action向View传递数据:

1.ViewData

2.TempData

3.强类型Model 

我们先来看看ViewContext,其有3个Virtual 属性:

public   class  ViewContext : ControllerContext
{
  
public   virtual  TempDataDictionary TempData {  get set ; }
  
public   virtual  IView View {  get set ; }
  
public   virtual  ViewDataDictionary ViewData {  get set ; }
 ...
}

ViewData TempData传递过程:

Action中的赋值语句实际上操作的是Controller类的ViewData和TempData属性, 此时并没有任何的数据传递.Action返回ViewResult,

  Controller的View方法会将Controller类的ViewData和TempData属性值传递给ViewResult,代码如下:
public   abstract   class  Controller : ControllerBase, IActionFilter,IAuthorizationFilter, IDisposable, IExceptionFilter, IResultFilter
{
...
protected   internal   virtual  ViewResult View(IView view,  object  model)
{
    
if  (model  !=   null )
    {
        
base .ViewData.Model  =  model;
    }
    
return   new  ViewResult { View  =  view, ViewData  =   base .ViewData, TempData  =   base .TempData };
}
...
}

 ViewResult的ExecuteResult根据ViewData和TempData构建ViewContext对象:

public   abstract   class  ViewResultBase : ActionResult
{
...
public   override   void  ExecuteResult(ControllerContext context)
{
    
if  (context  ==   null )
    {
        
throw   new  ArgumentNullException( " context " );
    }
    
if  ( string .IsNullOrEmpty( this .ViewName))
    {
        
this .ViewName  =  context.RouteData.GetRequiredString( " action " );
    }
    ViewEngineResult result 
=   null ;
    
if  ( this .View  ==   null )
    {
        result 
=   this .FindView(context);
        
this .View  =  result.View;
    }
    TextWriter writer 
=  context.HttpContext.get_Response().get_Output();
    ViewContext viewContext 
= new ViewContext(context, this.View, this.ViewData, this .TempData, writer);
    
this .View.Render(viewContext, writer);
    
if  (result  !=   null )
    {
        result.ViewEngine.ReleaseView(context, 
this .View);
    }
}
...
}
ViewContext对象最终会传递给ViewPage, 也就是说ViewData和TempData集合传递到了ViewPage.  实际上ViewData对象并不是通过ViewContext传递到ViewPage中的。
ViewPage上的ViewData是一个单独的属性,它继承自:IVeiwContainer
public   interface  IViewDataContainer
{
    
//  Properties
    ViewDataDictionary ViewData {  get set ; }
}

TempData在Controller的基类ControllerBase中定义

public   abstract   class  ControllerBase : IController
{
... 
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;
    }
}
 ...
}

TempData其实访问的是ViewContext.TempData

ViewPage Code如下:

[FileLevelControlBuilder( typeof (ViewPageControlBuilder))]
public   class  ViewPage : Page, IViewDataContainer
{
   ...
   public  ViewDataDictionary ViewData
   {
   
   get
   
   {
        
   if  ( this ._viewData  ==   null )
       
   {
           
   this .SetViewData( new  ViewDataDictionary());
      
   }
       
   return   this ._viewData;
   
   }
    
   set
   
   {
       
   this .SetViewData(value);
   
   }
   }
   public  TempDataDictionary TempData
   {
   
   get
   
   {
       
   return   this .ViewContext.TempData;
   
   }
   }
   ...
}

ViewData 和TempData传值如下:

public   class HomeController : Controller
    {
        
public  ActionResult Index()
        {
            ViewData[
"ViewData"= "ViewData";
            TempData[
"TempData"= "TempData"
;
            
return  View();
        }
    }

 在View中我们如下使用:

< asp:Content  ID ="Content2"  ContentPlaceHolderID ="MainContent"  runat ="server" >
ViewData传值:
<%=ViewData["ViewData"]%><br />
TempData传值:
<%=TempData["TempData"]%>

</ asp:Content >
ViewData只能在当前Action中有效
TempData可以类似于Session一样到其它页面仍然存在,但仅仅局限于这两个前后相连的页面(只能经过一次Controller传递)
TempData一般用于临时的缓存内容或抛出错误页面时传递错误信息 

强类型Model传值如下:

1. 我们需要Create一个Model类:

  public   class  Movie
    {
        
public   int  Id {  get set ; }
        
public   string  Title {  get set ; }
        
public   string  Director {  get set ; }
    }

2. Create一个View:

ViewName:Index

Check:Cerate aStrongly-typed view

选择刚Create的Movie Model

Scaffold template:选择List

点击ADD创建View

VS自动生成如下Code:

<% @ Page Title = ""  Language = " C# "  MasterPageFile = " ~/Views/Shared/Site.Master "  Inherits = " System.Web.Mvc.ViewPage<Jeriffe.Web.MVC.MovieApp.Movie> "   %>
< asp:Content  ID ="Content1"  ContentPlaceHolderID ="TitleContent"  runat ="server" >
    Details
</ asp:Content >
< asp:Content  ID ="Content2"  ContentPlaceHolderID ="MainContent"  runat ="server" >
< h2 > Details </ h2 >
< fieldset >
    
< legend > Movie </ legend >
    
< div  class ="display-label" > Title </ div >
    
< div  class ="display-field" >
        
<% : Html.DisplayFor(model  =>  model.Title)  %>
    
</ div >
    
< div  class ="display-label" > Director </ div >
    
< div  class ="display-field" >
        
<% : Html.DisplayFor(model  =>  model.Director)  %>
    
</ div >
</ fieldset >
< p >
    
<% : Html.ActionLink( " Edit " " Edit " new  { id = Model.Id })  %>  |
    
<% : Html.ActionLink( " Back to List " " Index " %>
</ p >
</ asp:Content >

 ViewPage的Model属性就是一个强类型对象, 在这里就是Movie.page页面指令可以看出, 这里的页面继承自ViewPage<Model>类, 而不是ViewPage.

ViewPage<TModel> Code如下:

public   class  ViewPage < TModel >  : ViewPage
{
    
//  Fields
     private  ViewDataDictionary < TModel >  _viewData;

    
//  Methods
     public  ViewPage();
    
public   override   void  InitHelpers();
    
protected   override   void  SetViewData(ViewDataDictionary viewData);

    
//  Properties
     public  AjaxHelper < TModel >  Ajax {  get set ; }
    
public  HtmlHelper < TModel >  Html {  get set ; }
    
public TModel Model { get ; }
    
public  ViewDataDictionary < TModel >  ViewData {  get set ; }
}

 

 

 

 

 

 

 

你可能感兴趣的:(asp.net)