Are they referring to the same underlying object? Always? Sometimes?
For Default WebFormView always, If you write your own View Engine this may different depends on you how you will implement it,
I think it is worth to just check what is going on behind the scene, I will just show important part of the classes,
What is ViewData? A simple Dictionary containing an extra Property Model used to pass data from controller to view,
public class ViewDataDictionary : IDictionary<string, object>,ICollection<KeyValuePair<string, object>>, IEnumerable<KeyValuePair<string, object>>,
IEnumerable
{
public object Model { get; set; }
.................
}
In your Controller Action you can access ViewData (and ViewData.Model), which is defined in Controller base class ControllerBase,
public abstract class ControllerBase : IController
{
.............
public ViewDataDictionary ViewData { get; set; }
}
When you return View() from action then it will call the given action,
It simply save the Controller.ViewData inside ViewResult.ViewData and return ViewResult(which inherits from ActionResult), ViewResult class is given below,
public class ViewResult : ActionResult
{
.................................................................
public override void ExecuteResult(ControllerContext context);
public ViewDataDictionary ViewData { get {...}; set {...}; }
public IViewEngine ViewEngine { get {...}; set {...}; }
public string ViewName { get {...}; set {...}; }
}
Actually Your Action is called by an ActionInvoker to recieve ActionResult,
Next the after recieving ViewResult from above View method, ActionInvoker just call ViewResult.ExecuteResult
public override void ExecuteResult(ControllerContext context)
{
.....................................................
ViewContext viewContext = new ViewContext(context, this.View, this.ViewData, this.TempData);
this.View.Render(viewContext, context.HttpContext.Response.Output);
........................................
}
ViewResult.ExecuteResult create an instance of ViewContext object, passing the controller ViewData in constructor, here is the ViewContext class,
public class ViewContext : ControllerContext {
public ViewContext(HttpContextBase httpContext, RouteData routeData, ControllerBase controller, IView view, ViewDataDictionary viewData, TempDataDictionary tempData)
: base(httpContext, routeData, controller) {
if (view == null) {
throw new ArgumentNullException("view");
}
ViewPage has Html Property which of type HtmlHelper, when creating HtmlHelper instance we passing the same ViewContext instance used in RenderViewPage method and the current ViewPage,
Here is HtmlHelper
public partial class HtmlHelper {
private RouteCollection _routeCollection;
public HtmlHelper(ViewContext viewContext, IViewDataContainer viewDataContainer) {
if (viewContext == null) {
throw new ArgumentNullException("viewContext");
}
if (viewDataContainer == null) {
throw new ArgumentNullException("viewDataContainer");
}
ViewContext = viewContext;
ViewDataContainer = viewDataContainer;
}
internal RouteCollection RouteCollection {
get {
if (_routeCollection == null) {
_routeCollection = RouteTable.Routes;
}
return _routeCollection;
}
set {
_routeCollection = value;
}
}
public ViewContext ViewContext {
get;
private set;
}
So we say that Html.ViewContext=ViewPage.ViewContext and Html.ViewData = ViewPage.ViewData,
Therefore, Html.ViewContext.ViewData= ViewPage.ViewContext.ViewData = ViewPage.ViewData = Html.ViewData = Controller.ViewData = ViewContext.ViewData = View.ViewData,
"And whoever is removed away from the Fire and admitted to Paradise, he indeed is successful." (The Holy Quran)
Excellent Windows VPS Hosting Imran Baloch MVP, MVB, MCP, MCTS, MCPD
fastfasterfa...
Participant
919 Points
206 Posts
HtmlHelper.ViewData vs. HtmlHelper.ViewContext.ViewData
Jun 02, 2010 11:27 PM|LINK
Is there any difference between accessing view data using HtmlHelper.ViewData vs. using HtmlHelper.ViewContext.ViewData?
KeFang Chen ...
Star
8329 Points
852 Posts
Re: HtmlHelper.ViewData vs. HtmlHelper.ViewContext.ViewData
Jun 04, 2010 06:41 AM|LINK
Hi,
There is little difference.
The HtmlHelper.ViewData returns a ViewDataDictionary<TModel> object while the HtmlHelper.ViewContext.ViewData returns a ViewDataDictionary object.
fastfasterfa...
Participant
919 Points
206 Posts
Re: HtmlHelper.ViewData vs. HtmlHelper.ViewContext.ViewData
Jun 04, 2010 08:36 PM|LINK
"little difference" can mean different things...
Are they referring to the same underlying object? Always? Sometimes?
imran_ku07
All-Star
45785 Points
7698 Posts
MVP
Re: HtmlHelper.ViewData vs. HtmlHelper.ViewContext.ViewData
Jun 05, 2010 04:43 AM|LINK
For Default WebFormView always, If you write your own View Engine this may different depends on you how you will implement it,
I think it is worth to just check what is going on behind the scene, I will just show important part of the classes,
What is ViewData? A simple Dictionary containing an extra Property Model used to pass data from controller to view,
public class ViewDataDictionary : IDictionary<string, object>,ICollection<KeyValuePair<string, object>>, IEnumerable<KeyValuePair<string, object>>,
IEnumerable
{
public object Model { get; set; }
.................
}
In your Controller Action you can access ViewData (and ViewData.Model), which is defined in Controller base class ControllerBase,
public abstract class ControllerBase : IController
{
.............
public ViewDataDictionary ViewData { get; set; }
}
When you return View() from action then it will call the given action,
protected virtual ViewResult View(IView view, object model)
{
if (model != null)
{
base.ViewData.Model = model;
}
ViewResult result = new ViewResult();
result.View = view;
result.ViewData = this.ViewData;
result.TempData = this.TempData;
return result;
}
It simply save the Controller.ViewData inside ViewResult.ViewData and return ViewResult(which inherits from ActionResult), ViewResult class is given below,
public class ViewResult : ActionResult
{
.................................................................
public override void ExecuteResult(ControllerContext context);
public ViewDataDictionary ViewData { get {...}; set {...}; }
public IViewEngine ViewEngine { get {...}; set {...}; }
public string ViewName { get {...}; set {...}; }
}
Actually Your Action is called by an ActionInvoker to recieve ActionResult,
Next the after recieving ViewResult from above View method, ActionInvoker just call ViewResult.ExecuteResult
public override void ExecuteResult(ControllerContext context)
{
.....................................................
ViewContext viewContext = new ViewContext(context, this.View, this.ViewData, this.TempData);
this.View.Render(viewContext, context.HttpContext.Response.Output);
........................................
}
ViewResult.ExecuteResult create an instance of ViewContext object, passing the controller ViewData in constructor, here is the ViewContext class,
public class ViewContext : ControllerContext {
public ViewContext(HttpContextBase httpContext, RouteData routeData, ControllerBase controller, IView view, ViewDataDictionary viewData, TempDataDictionary tempData)
: base(httpContext, routeData, controller) {
if (view == null) {
throw new ArgumentNullException("view");
}
ViewData = viewData;
TempData = tempData;
View = view;
}
public ViewContext(ControllerContext controllerContext, IView view, ViewDataDictionary viewData, TempDataDictionary tempData)
: this(GetControllerContext(controllerContext).HttpContext,
GetControllerContext(controllerContext).RouteData,
GetControllerContext(controllerContext).Controller,
view,
viewData,
tempData) {
}
public TempDataDictionary TempData {
get;
private set;
}
public IView View {
get;
private set;
}
public ViewDataDictionary ViewData {
get;
private set;
}
}
ViewContext.ViewData become synchrininze Controller ViewData,
After creating ViewContext, the above code call the View.Render method,
public virtual void Render(ViewContext viewContext, TextWriter writer)
{
..............................
object obj = this.BuildManager.CreateInstanceFromVirtualPath(this.ViewPath, typeof(object));
.........................................................
ViewPage page = obj as ViewPage;
if (page != null)
{
this.RenderViewPage(viewContext, page);
}
else
{
ViewUserControl control = obj as ViewUserControl;
if (control != null)
this.RenderViewUserControl(viewContext, control);
}
}
It will just create an dynamic page, call whether View.RenderViewPage or View.RenderViewUserControl,
and here is RenderViewPage given below
void RenderViewPage(ViewContext context, ViewPage page)
{
if (!string.IsNullOrEmpty(this.MasterPath))
page.MasterLocation = this.MasterPath;
page.ViewData = context.ViewData;
page.RenderView(context);
}
RenderViewPage just set ViewContext.ViewData=View.ViewData, Now we can say that, Controller ViewData = ViewContext.ViewData = View.ViewData,
The above method will then call ViewPage.RenderView. Just now see what is inside ViewPage class,
public class ViewPage : Page, IViewDataContainer {
public virtual void RenderView(ViewContext viewContext) {
ViewContext = viewContext;
InitHelpers();
}
public HtmlHelper Html {
get;
set;
}
public ViewContext ViewContext {
get;
set;
}
public ViewDataDictionary ViewData {
get {
if (_viewData == null) {
SetViewData(new ViewDataDictionary());
}
return _viewData;
}
set {
SetViewData(value);
}
}
public virtual void InitHelpers() {
Html = new HtmlHelper(ViewContext, this);
}
public virtual void RenderView(ViewContext viewContext) {
ViewContext = viewContext;
InitHelpers();
}
protected virtual void SetViewData(ViewDataDictionary viewData) {
_viewData = viewData;
}
}
ViewPage has Html Property which of type HtmlHelper, when creating HtmlHelper instance we passing the same ViewContext instance used in RenderViewPage method and the current ViewPage,
Here is HtmlHelper
public partial class HtmlHelper {
private RouteCollection _routeCollection;
public HtmlHelper(ViewContext viewContext, IViewDataContainer viewDataContainer) {
if (viewContext == null) {
throw new ArgumentNullException("viewContext");
}
if (viewDataContainer == null) {
throw new ArgumentNullException("viewDataContainer");
}
ViewContext = viewContext;
ViewDataContainer = viewDataContainer;
}
internal RouteCollection RouteCollection {
get {
if (_routeCollection == null) {
_routeCollection = RouteTable.Routes;
}
return _routeCollection;
}
set {
_routeCollection = value;
}
}
public ViewContext ViewContext {
get;
private set;
}
protected ViewDataDictionary ViewData {
get {
return ViewDataContainer.ViewData;
}
}
}
So we say that Html.ViewContext=ViewPage.ViewContext and Html.ViewData = ViewPage.ViewData,
Therefore, Html.ViewContext.ViewData= ViewPage.ViewContext.ViewData = ViewPage.ViewData = Html.ViewData = Controller.ViewData = ViewContext.ViewData = View.ViewData,
Excellent Windows VPS Hosting
Imran Baloch MVP, MVB, MCP, MCTS, MCPD