TIHIDI: Implement a simple controller rendering in Sitecore MVC

This blog post will go through how I setup a basic Controller rendering using Glass Mapper Model.

Visit http://www.glass.lu/mapper/sc for more information on Glass Mapper for Sitecore.

TIHIDI: Stands for This Is How I Do It. I am going to write a series of blog posts going through how I do Sitecore related work. Hope it helps you!

We are going to use the same infrastructure as my previous post TIHIDI: Implement a simple view rendering in Sitecore MVC and Glass.

Keeping the model as is, we need to add the code to render this via a Controller Rendering. This functionality really does not need a controller rendering as we were able to do this in a view rendering but I wanted to give you an example.

Before we get into controllers, we need to setup a couple of things related to Glass and Business Logic.

I setup a ControllerSCContext similar to Nathanael Mann (the Mann). You can read about it further here. Why do I do it this way? I do not know, I was taught by the master(s) to do it this way. If there is a more efficient way to do it, please send me links.

using Glass.Mapper.Sc;

namespace TIHIDI.Business.GlassSC
{
    public interface IControllerSCContext : ISitecoreContext
    {
        T GetDataSource() where T : class;

        T GetRenderingParameters() where T : class;
    }
}

using Glass.Mapper.Sc;
using Sitecore.Mvc.Presentation;
using System;

namespace TIHIDI.Business.GlassSC
{
    public class ControllerSCContext: SitecoreContext, IControllerSCContext
    {
        private IGlassHtml _glassHtml;

        public ControllerSCContext(IGlassHtml glassHtml)
        {
            _glassHtml = glassHtml;
        }

        public T GetRenderingParameters() where T : class
        {
            if (RenderingContext.CurrentOrNull != null)
            {
                string parameters = RenderingContext.CurrentOrNull.Rendering["Parameters"];
                if (String.IsNullOrEmpty(parameters))
                {
                    return _glassHtml.GetRenderingParameters(parameters);
                }
            }
            return default(T);

        }

        public T GetDataSource() where T : class
        {
            string dataSource = RenderingContext.CurrentOrNull.Rendering.DataSource;

            if (String.IsNullOrEmpty(dataSource))
            {
                return default(T);
            }

            Guid dataSourceId;

            return Guid.TryParse(dataSource, out dataSourceId)

                ? GetItem(dataSourceId)

                : GetItem(dataSource);
        }

        /// 
        /// if the rendering context and data source has been set then returns the data source item, otherwise returns the context item.
        /// 
        /// 
        /// 
        /// 
        /// 
        public T GetControllerItem(bool isLazy = false, bool inferType = false)
        where T : class
        {
            T renderingItem;
            if (RenderingContext.Current == null || RenderingContext.Current.Rendering == null || string.IsNullOrEmpty(RenderingContext.Current.Rendering.DataSource))
            {
                return GetCurrentItem(false, false);
            }
            try
            {
                renderingItem = this.GetRenderingItem(isLazy, inferType);
            }
            catch (InvalidOperationException invalidOperationException)
            {
                renderingItem = GetCurrentItem(false, false);
            }
            return renderingItem;
        }

        /// 
        /// Returns the data source item.
        /// 
        /// 
        /// 
        /// 
        /// 
        public virtual T GetRenderingItem(bool isLazy = false, bool inferType = false)
        where T : class
        {
            if (RenderingContext.Current == null || RenderingContext.Current.Rendering == null || string.IsNullOrEmpty(RenderingContext.Current.Rendering.DataSource))
            {
                return default(T);
            }
            return GetItem(RenderingContext.Current.Rendering.DataSource, isLazy, inferType);
        }
    }
}

Once that is done, I setup my business logic code.

using TIHIDI.Models.Templates.Content;

namespace TIHIDI.Business.Content
{
    public interface IContentLogic
    {
        ITextBlock GetTextBlock();
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TIHIDI.Business.GlassSC;
using TIHIDI.Models.Templates.Content;

namespace TIHIDI.Business.Content
{
    public class ContentLogic : IContentLogic
    {
        private readonly IControllerSCContext _currentContext;

        public ContentLogic(IControllerSCContext currentContext)
        {
            _currentContext = currentContext;
        }

        public ITextBlock GetTextBlock()
        {
            return _currentContext.GetDataSource();
        }
    }
}

I know the code is light but this shows you where the logic part of the code is supposed to be. I like my controllers as lean as possible. The next step is to define a controller.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using TIHIDI.Business.Content;

namespace TIHIDI.Web.Controllers
{
    public class ContentController : Controller
    {
        private readonly IContentLogic _contentLogic;

        public ContentController(IContentLogic contentLogic)
        {
            _contentLogic = contentLogic;
        }

        public ActionResult RenderTextBlock()
        {
            return View(_contentLogic.GetTextBlock());
        }
    }
}

We also need to register our new interfaces with Simple Injector.

            container.Register(()=> new ControllerSCContext(container.GetInstance()));
            container.Register();

Once that is done, its time to just copy our view rendering code since its going to be exactly the same. Create a new view under Views\Content.

@inherits Glass.Mapper.Sc.Web.Mvc.GlassView
@using Sitecore.Mvc

@if (Model != null)
{
    

@Editable(Model, y => y.Heading)

@Editable(Model, y => y.SubHeading)

@Editable(Model, y => y.Content)
}

Now that its all wired up, lets build and publish.

Setup a controller rendering in Sitecore to map this new controller.
cview1

Modify your item’s presentation to include this new rendering and fire it up.

view5
view3

If you have any questions or concerns, please get in touch with me. (@akshaysura13 on twitter or on Slack).

4 thoughts on “TIHIDI: Implement a simple controller rendering in Sitecore MVC”

  1. Where did you register the interfaces with injector? In global.asax or in custom pipeline? Is there any best practice?

  2. Where did you register new interfaces with Simple Injector? in custom pipeline or global.asax? Is there any best practise?

Leave a Reply

Your email address will not be published. Required fields are marked *