Moving to Sitecore MVC

This article is based on a presentation I gave at the Bristol Sitecore User Group June 2015. It is aimed at Sitecore developers looking to move to Sitecore MVC from WebForms.
09 October 2015

#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

  1. Swap out a rendering and datasource in a single step within the experience editor, or
  2. 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:

  1. enter the name of a controller item (described above) into the Controller Name field leaving Action Name blank, or
  2. enter Controller Name and Action 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)

Html Extension Methods (used in cshtml views)
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.

 

Useful classes/methods for Controllers and Models
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:

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

WebForms Apocalypse Meme

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.

Tags: ASP.NET MVCSitecore MVC
comments powered by Disqus