Вы находитесь на странице: 1из 2

Sitecore MVC

View Context Stack Diagram and Introduction


David Morrison
Twitter: @dmo_sc
Diagram 1
View Context
Stack
View Layout
View Context
View Rendering 2
View Context
View Rendering 3
View Context
View Rendering 1
View Context
View
Data
View Rendering 1
View Context Model
Shared
View Data
Dictionary
Any Model
IRendering Model
IRendering Model
IRendering Model
IRendering Model
Sitecore Controller
View Context
View Rendering 1
Placeholder: Main
Sitecore MVC View Context Stack
Rev 02
David Morrison
Twitter: @dmo_sc
View
Data
View
Bag
View Layout
View Context Model
Create Placeholder: Main
View Layout
Sitecore Controller
View Context
Sitecore Controller
View
Data
View
Bag Model
View
Bag
Create Placeholder: PH1
View
Data
View Rendering 1
View Context Model
View Rendering 1
Placeholder: Main
View
Data
View
Bag
View Rendering 2
View Context Model
Create Placeholder: PH2
View Rendering 2
Placeholder: PH1
View
Data
View
Bag
View Rendering 3
View Context Model
View Rendering 3
Placeholder: PH2

Introduction
There are a couple important stacks provided by the Sitecore MVC ContextService API. The ViewContext stack is one of
the more useful when you are trying to share data between a view rendering and a controller or across multiple view
renderings. The ContextService API is worthy of its own discussion but this introduction will focus on just one stack.
Sitecore MVC brings the dynamic placeholder rendering pattern to MVC and with it new conventions that developers
need to know. The View Context stack plays an integral part by keeping track of the hierarchy of ViewContext objects
created by the recursive nature of layouts, placeholders and renderings used to create a complex tree of HTML output.
The ViewContext stack is available as a list using the following syntax
Sitecore.Mvc.Common.ContextService.Get().GetInstances<ViewContext>()
In Microsoft MVC, the ViewContext object is used for passing data from the controller to the desired view, typically by
populating a model. The controller action sets the Model property to the desired view model and any other data in the
view data dictionary. The view is rendered by the Razor rendering engine and the view model properties and view data
dictionary are used to output HTML.
Sitecore MVC provides a default route and controller implementation so that you dont need to unless the situation
requires. You can do a lot with just the default controller. The ViewContext from the default or a custom controller is the
topmost object on the ViewContext stack in the center of Diagram 1. Some applications will use a custom controller to
set the Model in the ViewContext stack to be used later. Dynamic views can easily peek at the ViewContext stack to
quickly get properties from the topmost or parent view models.
The default controller, the presentation engine and many pipelines take care of everything up until the point where the
HTML needs to be rendered. Sitecore developers are responsible at a minimum for providing Razor views and populating
any view models. The mvc.getXmlLayoutDefinition pipeline determines which views to render by parsing the XML
presentation settings on each content item and populating the context PageDefinition object.
Sitecore MVC View Layouts and View Renderings still use a ViewContext but additional ViewContext objects are created,
one for each dynamic view on the page. The dynamic views do not use a controller so the model, if defined, is initialized
instead by the mvc.getModel pipeline and added to the ViewContext. All dynamic view models must implement the
IRenderingModel interface.
The Layout View is the first view to be rendered so its ViewContext object is always the second on the stack and second
on Diagram 1. Placeholders defined in the Layout View begin the process of executing the dynamic views. The rendering
process is repeated for every dynamic view in every placeholder.
When the presentation engine starts to render each individual dynamic view rendering, a new ViewContext is placed on
the stack. The ViewContext Model is initialized and set. When the rendering is finished, the ViewContext object is
popped off the stack and the previous ViewContext object resumes its role as the context. You wouldnt want view
model data from one view unintentionally spilling over into other views. On Diagram 1 this starts at the third object level
and continues down as more placeholders are nested in dynamic views.
Dont be distracted at this point by the multiple controller types that Sitecore MVC supports. Sitecore MVC can execute
a couple different types of controllers during a single request. There is only one primary controller that follows the full
MVC lifecycle. If you use the default Sitecore route, the primary controller is determined by the Sitecore route handler
and CreateController pipeline. This is the same type of controller that you would expect to find in a typical Microsoft
MVC project. You might be wondering about ControllerRendering items. A Controller Rendering however does not
follow the full lifecycle and the result is rendered inline as a string.
The primary controller and the first ViewContext on the stack is probably the most useful when just getting started.
Traditionally in MVC you just have a single controller and a single primary view (followed by partial views). In Sitecore
MVC, you can set a custom controller by name on the Controller field on all content items and the template standard
values. By providing your own controller, views can quickly make use of the topmost ViewContext object to share data.
Views can always rely on that ViewContext to be there in any view renderings and model initialization method.
The code fragment below demonstrates how to get the ViewContext for the primary controller at any point during the
rendering process and then get the primary view model.
var topViewContext = Sitecore.Mvc.Common.ContextService.Get().GetInstances<ViewContext>().FirstOrDefault();
var topViewModel = topViewContext.ViewData.Model;
It is also important to understand that every View Context object shares the same View Data dictionary even though the
model is different. When a new ViewContext is created, the ViewData dictionary is set by reference from the previous
ViewContext (represented in orange on Diagram 1). This allows all views to share a single view data dictionary. This
dictionary is another mechanism that can be used to share data. Care must be taken to ensure that the views do not use
keys that unintentionally overlap with other views. By using the view context stack correctly with the populated view
models the dictionary key collision can be avoided programmatically.

Вам также может понравиться