Moving to Sitecore MVC
#1 Benefits of Sitecore MVC
Clean Razor Syntax
Available since MVC 3, razor provides very clear and easy to read syntax for front-end development which is easy for anyone to understand without knowing the internals of how the view model is created.
No more XSLT
Now that Sitecore provides View Renderings, there is no need to use XSLT renderings. View renderings require just the definition item in Sitecore plus a cshtml view which is easier to work with than XSLT.
DataSource available OOTB
When creating view renderings, no additional code is required to get the datasource of the rendering, meaning you can code a simple component without writing any C# code.
No more server controls
While the library of server controls in WebForms may help developers to build pages quickly (and in theory using drag and drop development) they bring the limitations of inflexible HTML markup and as soon as you need to implement non-standard behaviour, development time can increase dramatically. With MVC although you have to build every component and rendering from the ground-up, the time taken to achieve things is generally more predictable.
Better Separation of Concerns
This is essentially one of the key benefits of ASP.NET MVC over WebForms. Since the controller instantiates the model used by the view (and you design your model to provide exactly what the view needs) the view can be responsible solely for generating HTML markup and need not contain any logic beyond simple foreach and if/else constructs.
#2 What’s new in Sitecore MVC (In the content tree)
Models
Models are definition items that tell Sitecore what class to instantiate for a view rendering. They have a single field called Model Type
where the class is referenced in the form: YourNamespace.YourClass, YourAssemblyName
. This class should implement Sitecore.Mvc.Presentation.IRenderingModel
(or inherit from Sitecore.Mvc.Presentation.RenderingModel
from Sitecore.Mvc.dll).
View Renderings
In their simplest form, view renderings are the closest comparison to XSLTs of yore. You can create a view rendering using just the rendering definition item in Sitecore and a cshtml file. You don’t even have to create a model for them if you just want to display the content from your datasource item. This is the simplest way to create a rendering in Sitecore MVC.
You can also create a view rendering using a Model (described above). On the view rendering you select a model in the ‘Model’ field. When rendering, Sitecore looks at the model item and uses that to determine the model type to instantiate for the view.
With view renderings, you don’t need a controller as the model is automatically instantiated by the Sitecore controller.
More information on view renderings can be found in my tutorial about building a carousel with view renderings.
Item Renderings
Item renderings allow you to render a datasource item using the rendering assigned to that item. This allows you to
- Swap out a rendering and datasource in a single step within the experience editor, or
- Render an item from within a view or controller rendering using the rendering set for that item. In other words; you could render a list of items using different presentation for each item based on the rendering assigned to each item.
Controllers (optional)
Controller items (different to controller renderings) are simply items to specify a Controller Name
and Action Name
. These can be referenced by a controller rendering item.
See here for a tutorial about using item renderings.
Controller Renderings
These are the closest thing to generic ASP.NET MVC views/controllers. They consist of a rendering definition item plus a cshtml view and the corresponding controller. On the controller rendering definition item, you can either:
- enter the name of a controller item (described above) into the
Controller Name
field leavingAction Name
blank, or - enter
Controller Name
andAction Name
from your code.
I've written a tutorial about controller renderings which explains this concept in more detail.
#3 What’s new in Sitecore MVC (In the API)
Sitecore().Field()
- Renders a field of an item, equivalent to
<sc:FieldRenderer />
Sitecore().Placeholder()
- Renders a placeholder, equivalent to
<sc:Placeholder />
Sitecore().ItemRendering()
- Renders an item using the rendering set in the “Renderers” field. This means you can call a rendering within a rendering.
Sitecore().ViewRendering()
- Statically binds a cshtml rendering onto another rendering without creating the rendering definition item. You might use this technique for a header or menu component, if you don’t want/need the rendering to be configurable anywhere else.
Sitecore().Controller()
- Statically binds a controller, see the warning here about using this http://cardinalcore.co.uk/2015/05/15/did-you-really-mean-controller-in-sitecore-mvc/
Sitecore().Rendering()
- Statically binds a rendering. You pass in the ID of a controller or view rendering.
Sitecore.Mvc.Presentation
- The namespace containing the rendering-related classes in Sitecore MVC.
- This can be found by inspecting Sitecore.Mvc.dll using dotPeek
Sitecore.Mvc.Presentation.RenderingContext.Current.Rendering.Item
- The rendering datasouce item
Sitecore.Mvc.Presentation.RenderingContext.Current.ContextItem
- The context item (effectively the same as using
Sitecore.Context.Item
)
#4 What’s not new in Sitecore MVC
The good news: your current Sitecore knowledge is still valid!
- Template design
- Content structure and information architecture
- How to split a page into components
- Extending Sitecore e.g. UI customisation, (most) pipelines scheduled tasks etc
#5 How does Sitecore MVC differ from regular MVC
- No custom routes
- You don’t have to create a controller and action for every view
- No need to use:
- @RenderBody()
- @RenderSection(“YourSectionName”)
- @{ Layout = “~/Views/Shared/_SomeLayout.cshtml” }
#6 Choosing your MVC rendering types
View Renderings are good for:
- Simple widgets
- Structural components
Controller Renderings are good for:
- Complex components displaying data from multiple items
- Components involving business logic or retrieval of non-Sitecore data
- Components with forms
Item renderings are good for:
- Lists of items
- Lists of different types of items
#7 Other stuff you may want to use
Dependency Injection
Since controller dependency injection is so simple with MVC it is well worth using dependency injection if your project involves data from any external sources.
AutoMapper
This mainly applies to solutions where you are working with external data. AutoMapper can greatly reduce the bulk of code for mapping objects of your business layer into view models.
Unit Testing
Unit testability is one of the classic advantages of MVC and that advantage extends to Sitecore MVC as well. http://mhwelander.net/2014/04/30/unit-testing-sitecore-mvc/
#8 Gotchas
Posting back forms can be complicated!
My advice here is to capture form submissions client side with jQuery and submit form data via AJAX to a dedicated controller action.
Form more on posting forms in Sitecore MVC see:
- http://mhwelander.net/2014/05/28/posting-forms-in-sitecore-mvc-part-1-view-renderings/
- http://mhwelander.net/2014/05/30/posting-forms-in-sitecore-mvc-part-2-controller-renderings/
No ViewState/ControlState
Everything will be re-fetched with each hit unless you cache.
Security not “built-in” like WebForms
See my 5 security tips for working with forms in Sitecore MVC
ASP.NET MVC has no control hierarchy
This means you can’t pass data from one rendering to another (server side) as you can do with events or by accessing parent/child controls in WebForms. This is actually a plus as doing that leads to tight coupling which is best avoided anyway.
If you must pass data between MVC renderings/controllers, use HttpContext.Items but be aware that this is dependent on the order in which your renderings/controllers are invoked. Note HttpContext.Items data exists only for the duration of a request, this is how Sitecore persists Sitecore.Context.Item
.
Not all modules are MVC compatible
Check first before committing to using anything! WFFM now supports MVC :-) Modules which include UI (menu, components etc) are more likely to be written for WebForms and cause problems.
#9 How to persuade your boss
ASP.NET MVC is a stable platform
ASP.NET MVC is a stable and well-established platform (8 years old, CTP released in 2007)
Shares a lot of the core API with ASP.NET
This is a big deal
Sitecore has supported MVC since version 6.6*
* In my presentation, I incorrectly stated that Sitecore had supported MVC since version 6.4 - sorry for the mistake there :-(
Some changes made to MVC API circa V7, so this can be considered a stable API.
Most of Sitecore now built using MVC
A lot of the UI of Sitecore is built in MVC (using SPEAK UI)
Good way to attract new talent to your company
Great developers love to use and learn the latest technologies, so if you advertise a job requiring (or offering training in) ASP.NET MVC this will make your company much more attractive.
Don’t need to convert the whole solution at once
WebForms and MVC can happily co-exist. You could build most of your pages using MVC for simple components and then maybe build your payment form in WebForms (if you’re not so experienced with MVC).
Each page must be MVC OR WebForms
#10 The WebForms Apocalypse is Nigh
Be warned, Microsoft are no longer developing WebForms in ASP.NET 5! See http://stephenwalther.com/archive/2015/02/24/top-10-changes-in-asp-net-5-and-mvc-6.