Kentico 12 SP MVC Section view models

Laura Frese asked on May 7, 2020 22:21

I am trying to create sections. I reviewed the documentation here https://docs.kentico.com/k12sp/developing-websites/page-builder-development/developing-page-builder-sections/defining-section-properties and it says “Do not directly pass the property model to your section views. We strongly recommend creating a separate view model class, which you can then use to pass data to the section view." Then immediately go on to provide an example where the property model is passed to the view. So there isn’t an example of passing the view model for the section in the documentation. When I do try to pass the view model I get the error:

The model item passed into the dictionary is of type 'Kentico.PageBuilder.Web.Mvc.ComponentViewModel`1[Katapult.Web.Models.Sections.Column1SectionProperties]', but this dictionary requires a model item of type 'Katapult.Web.Models.Sections.Column1SectionViewModel'.

My Properties

public class Column1SectionProperties: ISectionProperties
{
    [EditingComponent(MediaFilesSelector.IDENTIFIER, Order = 1, Label = "Background Image")]
    [EditingComponentProperty(nameof(MediaFilesSelectorProperties.LibraryName), "Custom")]
    [EditingComponentProperty(nameof(MediaFilesSelectorProperties.AllowedExtensions), ".gif;.png;.jpg;.jpeg")]
    [EditingComponentProperty(nameof(MediaFilesSelectorProperties.MaxFilesLimit), 1)]
    public IList<MediaFilesSelectorItem> BackgroundImage { get; set; }
}

My view model

public class Column1SectionViewModel 
    {        
        public string BackgroundImageUrl { get; set; }
    }

My controller

[assembly: RegisterSection("Column1Section",
                          "1 Column section",
                          typeof(Column1SectionProperties),
                          IconClass = "icon-square")]
namespace Custom.Web.Controllers.Sections
{
    class Column1SectionController : SectionController<Column1SectionProperties>
    {
        public ActionResult Index()
        {
            Column1SectionProperties sp = GetProperties();
            string bgurl = String.Empty;
            var bg = sp.BackgroundImage?.FirstOrDefault();
            if (bg != null)
            {
                Guid g = bg.FileGuid;
                MediaFileInfo mediaFile = MediaFileInfoProvider.GetMediaFileInfo(g, SiteContext.CurrentSiteName);
                if (mediaFile != null)
                {
                    bgurl = MediaLibraryHelper.GetDirectUrl(mediaFile);
                }

var model = new Column1SectionViewModel
              {
               BackgroundImageUrl = bgurl
               }
return PartialView("Sections/_Column1Section", model);
       }

My view

@using Kentico.PageBuilder.Web.Mvc
@using Kentico.Web.Mvc
@using Custom.Web.Models.Sections

@model Column1SectionViewModel

<img src="@Model.BackgroundImageUrl">
@Html.Kentico().WidgetZone()

Correct Answer

Laura Frese answered on May 8, 2020 18:07

As you can see, the view is expecting the view model but the controller is passing the ComponentViewModel even though I am passing the viewmodel in the Index()

I reviewed the documentation again (https://docs.kentico.com/k12sp/developing-websites/page-builder-development/developing-page-builder-sections) and noticed that the assembly I was using was for the basic controller and for the custom controller the assembly is slightly different.

The basic registration has params Identifier, Name, and PropertiesType in that order whereas the custom controller has the params Identifier, ControllerType, Name

[assembly: RegisterSection("Column1Section",
                        typeof(Column1SectionController),
                          "1 Column section",                          
                          IconClass = "icon-square")]

was the fix, and my controller class was not public - this wasnt a problem when using the basic registration, since the class was never called. If I just changed the basic registration to

[assembly: RegisterSection("Column1Section",
                          "1 Column section",
                          typeof(Column1SectionController),
                          IconClass = "icon-square")]

I would get the error "Implementation of the section properties must implement ISectionProperties interface." So it really needs to be in that order as indicated in the documentation.

0 votesVote for this answer Unmark Correct answer

Recent Answers


Arjan van Hugten answered on May 8, 2020 09:59 (last edited on May 8, 2020 10:02)

Hi,

In the register section attribute the typeof needs to be the controller class. So it should be:

[assembly: RegisterSection("Column1Section", "1 Column section", typeof(Column1SectionController), IconClass = "icon-square")]

Other things you could check:

  • Having the view in the correct location (Views/Shared/Sections)
  • Returning a correct partial view when the background img is empty
0 votesVote for this answer Mark as a Correct answer

Laura Frese answered on May 8, 2020 18:05

The error I pasted was the wrong error. The actual error is

As you can see, the view is expecting the view model but the controller is passing the ComponentViewModel

0 votesVote for this answer Mark as a Correct answer

Laura Frese answered on May 8, 2020 18:06

The error I pasted was the wrong error. The actual error is

As you can see, the view is expecting the view model but the controller is passing the ComponentViewModel

0 votesVote for this answer Mark as a Correct answer

   Please, sign in to be able to submit a new answer.