ASP.NET MVC3 向View传递数据
一般来说我们使用3种方式通过Action向View传递数据:
1.ViewData
2.TempData
3.强类型Model
我们先来看看ViewContext,其有3个Virtual 属性:
{
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,
{
...
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 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);
}
}
...
}
{
// Properties
ViewDataDictionary ViewData { get ; set ; }
}
{
...
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如下:
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 ActionResult Index()
{
ViewData[ "ViewData"] = "ViewData";
TempData["TempData"] = "TempData" ;
return View();
}
}
在View中我们如下使用:
ViewData传值: <%=ViewData["ViewData"]%><br />
TempData传值:<%=TempData["TempData"]%>
</ asp:Content >
TempData可以类似于Session一样到其它页面仍然存在,但仅仅局限于这两个前后相连的页面(只能经过一次Controller传递)
强类型Model传值如下:
1. 我们需要Create一个Model类:
{
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:
< 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如下:
{
// 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 ; }
}