EDIT 1
I was able to get this functioning by overriding the GetModel() method after recieving some guidance from Gatogordo and Dawid Rutkowski and decompling the sitecore DLLs. See below for answer including working code.
Original Question
I'm working with the new SXA 1.4 module that Sitecore recently released. After a lot of trial and error I was able to get a basic custom control working and added to the SXA toolbox. I figured the logical next task was to update my control to use different Rendering Variants but I've run into some problems. I started by modifying based on these blog posts:
- http://unaverhoeven.ghost.io/2017/04/05/starting-with-sxa-part-1-custom-rendering-and-rendering-variants/
- https://ggullentops.blogspot.com/2017/03/variants-sxa-sitecore-rendering.html?spref=tw
Here are my updated code files:
CallToActionWithImageBackground.config
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
<sitecore>
<pipelines>
<ioc>
<processor type="Company.Feature.CallToActionWithImageBackground.Configurator.CallToActionWithImageBackgroundConfigurator, Company.Feature.CallToActionWithImageBackground" />
</ioc>
</pipelines>
</sitecore>
</configuration>
CallToActionWithImageBackgroundConfigurator.cs
using Sitecore.DependencyInjection;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Company.Feature.CallToActionWithImageBackground.Repositories;
using Company.Feature.CallToActionWithImageBackground.Controllers;
using Sitecore.XA.Foundation.IOC.Pipelines.IOC;
namespace Company.Feature.CallToActionWithImageBackground.Configurator
{
public class CallToActionWithImageBackgroundConfigurator : IocProcessor
{
public override void Process(IocArgs args)
{
args.ServiceCollection.AddTransient<ICallToActionWithImageBackgroundRepository, CallToActionWithImageBackgroundRepository>();
}
}
}
CallToActionWithImageBackgroundController.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Sitecore;
using Sitecore.Data;
using Sitecore.ExperienceEditor;
using Company.Feature.CallToActionWithImageBackground.Repositories;
using Sitecore.XA.Foundation.IoC;
using Sitecore.XA.Foundation.Mvc.Controllers;
using Sitecore.XA.Foundation.RenderingVariants.Controllers;
using Company.Feature.CallToActionWithImageBackground.Models;
namespace Company.Feature.CallToActionWithImageBackground.Controllers
{
public class CallToActionWithImageBackgroundController : VariantsController
{
private readonly ICallToActionWithImageBackgroundRepository _repository;
public CallToActionWithImageBackgroundController(ICallToActionWithImageBackgroundRepository repository)
{
this._repository = repository;
}
protected object GetVariantsModel()
{
return _repository.GetModel();
}
//public ActionResult BlogList()
//{
// var model = _repository.GetModel();
// return View(model);
//}
}
}
CallToActionWithImageBackgroundModel.cs
using Sitecore.XA.Foundation.Multisite.LinkManagers;
using Sitecore.XA.Foundation.Mvc.Models;
using Sitecore.XA.Foundation.RenderingVariants.Models;
using Sitecore.XA.Foundation.Variants.Abstractions.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace Company.Feature.CallToActionWithImageBackground.Models
{
public class CallToActionWithImageBackgroundModel : VariantsRenderingModel
{
}
}
CallToActionWithImageBackgroundRepository.cs
using Company.Feature.CallToActionWithImageBackground.Models;
using Sitecore.XA.Foundation.Multisite.LinkManagers;
using Sitecore.XA.Foundation.Mvc.Repositories.Base;
using Sitecore.XA.Foundation.RenderingVariants.Repositories;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
//using static Sitecore.Configuration.Settings;
namespace Company.Feature.CallToActionWithImageBackground.Repositories
{
public class CallToActionWithImageBackgroundRepository : VariantsRepository, ICallToActionWithImageBackgroundRepository
{
//public T GetModel<T>(object model) where T : IRenderingModelBase
//{
// FillBaseProperties(model);
// return (T)model;
//}
//public CallToActionWithImageBackgroundModel GetModel<CallToActionWithImageBackgroundModel>(object model)
//{
// FillBaseProperties(model);
// return (CallToActionWithImageBackgroundModel)model;
//}
public override IRenderingModelBase GetModel()
{
CallToActionWithImageBackgroundModel model = new CallToActionWithImageBackgroundModel();
FillBaseProperties(model);
return model;
}
}
}
ICallToActionWithImageBackgroundRepository.cs
using Sitecore.XA.Foundation.Mvc.Repositories.Base;
using Sitecore.XA.Foundation.RenderingVariants.Repositories;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace Company.Feature.CallToActionWithImageBackground.Repositories
{
public interface ICallToActionWithImageBackgroundRepository : IVariantsRepository
{
}
}
Call to Action With Image Background.cshtml
@using Sitecore.XA.Foundation.MarkupDecorator.Extensions
@using Sitecore.XA.Foundation.SitecoreExtensions.Extensions
@using Sitecore.Data;
@using Sitecore.Extensions
@using Sitecore.XA.Foundation.MarkupDecorator.Extensions
@using Sitecore.XA.Foundation.SitecoreExtensions.Extensions
@using Sitecore.XA.Foundation.RenderingVariants.Extensions
@using Sitecore.XA.Foundation.RenderingVariants.Fields
@using Sitecore.XA.Foundation.Variants.Abstractions.Fields
@model Company.Feature.CallToActionWithImageBackground.Models.CallToActionWithImageBackgroundModel
@if (Model.DataSourceItem != null || Html.Sxa().IsEdit)
{
<div @Html.Sxa().Component("call-to-action-with-image-background-component", Model.Attributes)>
<div class="component-content">
@if (Model.DataSourceItem == null)
{
@Model.MessageIsEmpty
}
else
{
foreach (BaseVariantField variantField in Model.VariantFields)
{
@Html.RenderingVariants().RenderVariant(variantField, Model.Item, Model.RenderingWebEditingParams)
}
}
</div>
</div>
}
And here are my settings within Sitecore:
And the error message I receive:
11708 15:59:56 ERROR Failed to render rendering
Exception: System.Web.HttpUnhandledException
Message: An unhandled exception occurred.
Source: Sitecore.Mvc
at Sitecore.Mvc.Pipelines.MvcEvents.Exception.ShowAspNetErrorMessage.ShowErrorMessage(ExceptionContext exceptionContext, ExceptionArgs args)
at Sitecore.Mvc.Pipelines.MvcEvents.Exception.ShowAspNetErrorMessage.Process(ExceptionArgs args)
at (Object , Object[] )
at Sitecore.Pipelines.CorePipeline.Run(PipelineArgs args)
at Sitecore.Pipelines.DefaultCorePipelineManager.Run(String pipelineName, PipelineArgs args, String pipelineDomain)
at Sitecore.Mvc.Pipelines.PipelineService.RunPipeline[TArgs](String pipelineName, TArgs args)
at Sitecore.Mvc.Filters.PipelineBasedRequestFilter.OnException(ExceptionContext exceptionContext)
at System.Web.Mvc.ControllerActionInvoker.InvokeExceptionFilters(ControllerContext controllerContext, IList`1 filters, Exception exception)
at System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName)
at System.Web.Mvc.Controller.ExecuteCore()
at System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext)
at Sitecore.Mvc.Controllers.ControllerRunner.ExecuteController(Controller controller)
at Sitecore.Mvc.Controllers.ControllerRunner.Execute()
at Sitecore.Mvc.Presentation.ControllerRenderer.Render(TextWriter writer)
at Sitecore.Mvc.Pipelines.Response.RenderRendering.ExecuteRenderer.Render(Renderer renderer, TextWriter writer, RenderRenderingArgs args)
Nested Exception
Exception: System.InvalidOperationException
Message: The model item passed into the dictionary is of type 'Sitecore.XA.Foundation.RenderingVariants.Models.VariantListsRenderingModel', but this dictionary requires a model item of type 'Company.Feature.CallToActionWithImageBackground.Models.CallToActionWithImageBackgroundModel'.
Source: System.Web.Mvc
at System.Web.Mvc.ViewDataDictionary`1.SetModel(Object value)
at System.Web.Mvc.ViewDataDictionary..ctor(ViewDataDictionary dictionary)
at System.Web.Mvc.WebViewPage`1.SetViewData(ViewDataDictionary viewData)
at System.Web.Mvc.RazorView.RenderView(ViewContext viewContext, TextWriter writer, Object instance)
at System.Web.Mvc.ViewResultBase.ExecuteResult(ControllerContext context)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList`1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList`1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList`1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultWithFilters(ControllerContext controllerContext, IList`1 filters, ActionResult actionResult)
at System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName)
8140 16:00:05 ERROR Failed to render rendering
Exception: System.Web.HttpUnhandledException
Message: An unhandled exception occurred.
Source: Sitecore.Mvc
at Sitecore.Mvc.Pipelines.MvcEvents.Exception.ShowAspNetErrorMessage.ShowErrorMessage(ExceptionContext exceptionContext, ExceptionArgs args)
at Sitecore.Mvc.Pipelines.MvcEvents.Exception.ShowAspNetErrorMessage.Process(ExceptionArgs args)
at (Object , Object[] )
at Sitecore.Pipelines.CorePipeline.Run(PipelineArgs args)
at Sitecore.Pipelines.DefaultCorePipelineManager.Run(String pipelineName, PipelineArgs args, String pipelineDomain)
at Sitecore.Mvc.Pipelines.PipelineService.RunPipeline[TArgs](String pipelineName, TArgs args)
at Sitecore.Mvc.Filters.PipelineBasedRequestFilter.OnException(ExceptionContext exceptionContext)
at System.Web.Mvc.ControllerActionInvoker.InvokeExceptionFilters(ControllerContext controllerContext, IList`1 filters, Exception exception)
at System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName)
at System.Web.Mvc.Controller.ExecuteCore()
at System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext)
at Sitecore.Mvc.Controllers.ControllerRunner.ExecuteController(Controller controller)
at Sitecore.Mvc.Controllers.ControllerRunner.Execute()
at Sitecore.Mvc.Presentation.ControllerRenderer.Render(TextWriter writer)
at Sitecore.Mvc.Pipelines.Response.RenderRendering.ExecuteRenderer.Render(Renderer renderer, TextWriter writer, RenderRenderingArgs args)
Nested Exception
Exception: System.InvalidOperationException
Message: The model item passed into the dictionary is of type 'Sitecore.XA.Foundation.RenderingVariants.Models.VariantListsRenderingModel', but this dictionary requires a model item of type 'Company.Feature.CallToActionWithImageBackground.Models.CallToActionWithImageBackgroundModel'.
Source: System.Web.Mvc
at System.Web.Mvc.ViewDataDictionary`1.SetModel(Object value)
at System.Web.Mvc.ViewDataDictionary..ctor(ViewDataDictionary dictionary)
at System.Web.Mvc.WebViewPage`1.SetViewData(ViewDataDictionary viewData)
at System.Web.Mvc.RazorView.RenderView(ViewContext viewContext, TextWriter writer, Object instance)
at System.Web.Mvc.ViewResultBase.ExecuteResult(ControllerContext context)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList`1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList`1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList`1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultWithFilters(ControllerContext controllerContext, IList`1 filters, ActionResult actionResult)
at System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName)
I feel like I am doing something silly but I have never worked with Sitecore before so the learning curve has been rather drastic. Any ideas what I could be doing wrong?