
Megan Perry-Thibault (Customer) asked a question.
We are attempting to upgrade our site from 14.4 to 15.4 and everything is working smoothly for the most part except for one big issue with our Card Widget.
We have extended the built in Card Widget to include fields that dictate style and color (see attached). It works just fine on our production site (which is still on 14.4) but on our dev site (upgraded to 15.4) everywhere there is a view that references the extended view model, (Website.Sitefinity.Mvc.Models.Card.ExtCardViewModel) it throws back an error.
"Type : System.InvalidOperationException, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
Message : ‹‹‹The model item passed into the dictionary is of type 'Telerik.Sitefinity.Frontend.Card.Mvc.Models.Card.CardViewModel', but this dictionary requires a model item of type 'Website.Sitefinity.Mvc.Models.Card.ExtCardViewModel'.›››
Source : System.Web.Mvc"
We are not sure why this is suddenly happening but we need it resolved before we can upgrade our production server. If anyone has any insight on why this might be happening, that would be amazingly helpful.
Card View Model (ExtCardViewModel.cs)
- using System.Web;
- using Telerik.Sitefinity.Frontend.Card.Mvc.Models.Card;
- using Telerik.Sitefinity.Frontend.Mvc.Models;
- using Telerik.Sitefinity.Web;
-
- namespace FLDFS.MyFloridaCfo.Sitefinity.Mvc.Models.Card
- {
- public class ExtCardViewModel : CardViewModel
- {
- public ExtCardViewModel() : base()
- {
- }
- public bool OpenInNewTab {get; set;}
- public string CardTarget { get; set; }
- public bool FlexOrStatic { get; set; }
- public string CardHeight { get; set; }
- public string CardStyle { get; set; }
- public string CardWidth { get; set; }
-
- }
- }
Card Model (ExtCardModel.cs)
- using System;
- using Telerik.Sitefinity.Frontend.Card.Mvc.Models.Card;
- using Telerik.Sitefinity.Modules.Pages.Web.Services;
- using SfImage = Telerik.Sitefinity.Libraries.Model.Image;
- using System.ComponentModel;
- using Progress.Sitefinity.Renderer.Entities.Content;
- using Progress.Sitefinity.Renderer.Designers.Attributes;
- using System.Globalization;
- using System.Linq;
- using Telerik.Sitefinity.Configuration;
- using Telerik.Sitefinity.Data;
- using Telerik.Sitefinity.Modules;
- using Telerik.Sitefinity.Modules.GenericContent;
- using Telerik.Sitefinity.Modules.Libraries;
- using Telerik.Sitefinity.Modules.Pages;
- using Telerik.Sitefinity.Pages.Model;
- using Telerik.Sitefinity.Services;
- using Telerik.Sitefinity.Web;
-
- namespace FLDFS.MyFloridaCfo.Sitefinity.Mvc.Models.Card
- {
- [TypeConverter(typeof(ExpandableObjectConverter))]
- //The ReflectInheritedProperties attribute instructs Sitefinity to look at the concrete implementation of the class for resolving properties instead of the interface.
- [ReflectInheritedProperties]
- public class ExtCardModel : CardModel
- {
- public ExtCardModel() : base()
- {
- }
- /// <summary>
- /// New or Same Tab
- /// </summary>
- public bool OpenInNewTab { get; set; }
- public string Target()
- {
- if (OpenInNewTab == true)
- { return "_blank"; }
- else
- { return ""; }
- }
-
- /// <summary>
- /// Set Card Height
- /// </summary>
- public bool FlexOrStatic { get; set; }
- public string CardHeight()
- {
- if (FlexOrStatic == true)
- { return "full-height"; }
- else
- { return ""; }
- }
- public string CardStyle { get; set; }
-
- public string CardWidth { get; set; }
-
- public override CardViewModel GetViewModel()
- {
- var viewModel = new ExtCardViewModel()
- {
- Heading = this.Heading,
- Description = this.Description,
- ActionName = this.ActionName,
- ActionUrl = this.GetLinkedUrl(),
- CssClass = this.CssClass,
- CardTarget = this.Target(),
- CardHeight = this.CardHeight(),
- CardStyle = this.CardStyle,
- CardWidth = this.CardWidth,
- };
-
- SfImage image;
- if (this.ImageId != Guid.Empty)
- {
- image = this.GetImage();
- if (image != null)
- {
- viewModel.SelectedSizeUrl = this.GetSelectedSizeUrl(image);
- viewModel.ImageAlternativeText = image.AlternativeText;
- viewModel.ImageTitle = image.Title;
- }
- }
- return viewModel;
- }
- }
- }
Card View (Card.cshtml)
- @model FLDFS.MyFloridaCfo.Sitefinity.Mvc.Models.Card.ExtCardViewModel
- @using Telerik.Sitefinity.Frontend.Mvc.Helpers;
-
- @Html.StyleSheet(Url.Content("~/ResourcePackages/FLDFS/css/CardExt.min.css"), "head", true)
-
- @ if (string.Equals(Model.CardStyle, "hero"))
- {
- <hero>
- <div style="background: url( @Model.SelectedSizeUrl ) center center; background-size:cover">
- <div class="container text-box">
- <h2 class="h-1">@Html.HtmlSanitize(Model.Heading)</h2>
- <p>@Html.HtmlSanitize(Model.Description)</p>
- @if (!string.IsNullOrEmpty(Model.ActionName))
- {
- <a class="btn" href="@Html.UrlSanitize(Model.ActionUrl)" role="button">@Model.ActionName</a>
- }
- </div>
- </div>
- </hero>
- }
- else if (string.Equals(Model.CardStyle, "button"))
- {
- <cbtn-wrapper class="@Model.CardHeight">
- <cbtn class="@Model.CssClass @Model.CardWidth">
- <a href="@Html.UrlSanitize(Model.ActionUrl)" target="@Model.CardTarget">
- <div>
- @if (!string.IsNullOrEmpty(Model.Heading))
- {
- <h-3>@Html.HtmlSanitize(Model.Heading)</h-3>
- }
- @if (!string.IsNullOrEmpty(Model.Description))
- {
- <card-text style="line-height:1.2">@Html.HtmlSanitize(Model.Description)</card-text>
- }
- </div>
- </a>
- </cbtn>
- </cbtn-wrapper>
- }
- else
- {
- <card-wrapper class="@Model.CardHeight">
- <card-base class="@Model.CssClass">
- @if (!string.IsNullOrEmpty(Model.ActionUrl))
- {
- <div>
- @if (!string.IsNullOrEmpty(Model.SelectedSizeUrl))
- {
- <a href="@Html.UrlSanitize(Model.ActionUrl)" target="@Model.CardTarget"><img loading="lazy" class="card-img-top" src="@Model.SelectedSizeUrl" title="@Model.ImageTitle" alt="@Model.ImageAlternativeText" /></a>}
- </div>
- if (!string.IsNullOrEmpty(Model.ActionName))
- {
- <card-body>
- <div>
- @if (!string.IsNullOrEmpty(Model.Heading))
- {<card-title>@Html.HtmlSanitize(Model.Heading)</card-title>}
- @if (!string.IsNullOrEmpty(Model.Description))
- {<card-text>@Html.HtmlSanitize(Model.Description)</card-text>}
- </div>
- @if (!string.IsNullOrEmpty(Model.ActionName))
- {<div><a class="btn" target="@Model.CardTarget" href="@Html.UrlSanitize(Model.ActionUrl)">@Model.ActionName </a></div>}
- </card-body>
- }
- else
- {
- <div>
- <a href="@Html.UrlSanitize(Model.ActionUrl)" target="@Model.CardTarget">
- <card-body>
- @if (!string.IsNullOrEmpty(Model.Heading))
- {<card-title>@Html.HtmlSanitize(Model.Heading)</card-title>}
- @if (!string.IsNullOrEmpty(Model.Description))
- {<card-text><p style="margin-top:0">@Html.HtmlSanitize(Model.Description)</p></card-text>}
- </card-body>
- </a>
- </div>
- }
- }
- else
- {
- <img loading="lazy" class="card-img-top" src="@Model.SelectedSizeUrl" title="@Model.ImageTitle" alt="@Model.ImageAlternativeText" />
- <card-body>
- @if (!string.IsNullOrEmpty(Model.Heading))
- {
- <card-title>@Html.HtmlSanitize(Model.Heading)</card-title>
- }
- @if (!string.IsNullOrEmpty(Model.Description))
- {
- <card-text>
- <p style="margin-top:0">@Html.HtmlSanitize(Model.Description)</p>
- </card-text>
- }
- </card-body>
- }
- </card-base>
- </card-wrapper>
- }
THE BINDINGS! THANK YOU!
Apparently with the upgrade the global.asax file disappeared which took my model binding with it. (To answer your question - the extended model is bound per: https://community.progress.com/s/article/How-to-extend-built-in-MVC-Card-widget-to-have-a-custom-property-OpenInNewTab)