首页 > 解决方案 > EPiServer.Core.TypeMismatchException

问题描述

我是 EPIServer、asp.net 和 C# 开发的新手,并试图了解以下问题。

我从 Visual Studio 运行了一个 EPIServer CMS 实例。我打开了一个预先存在的测试页面,并将一个视频播放器块(包含一个 youtube 链接)添加到主内容区域。然后我发布了我的页面并在前端查看了它。

然后我返回编辑页面,单击视频播放器块并选择编辑,然后我被带到可以编辑此视频播放器块设置的页面,但 Visual Studio 停止,我得到一个 EPiServer Visual Studio 中的 .Core.TypeMismatchException 错误。

错误信息:

抛出异常:EPiServer.dll 中的“EPiServer.Core.TypeMismatchException” EPiServer.dll 中发生“EPiServer.Core.TypeMismatchException”类型的异常,但未在用户代码中处理 ID 为“9913_22802”的内容属于“Castle.Proxies”类型.VideoPlayerBlockProxy' 不继承所需类型'Example.Site.Models.Pages.SitePageData'

以下代码行在 Visual Studio 中被标记为问题的根源:

var currentPage = _contentLoader.Get<SitePageData>(currentContentLink);

这是一些上下文:

public virtual LayoutModel CreateLayoutModel(ContentReference currentContentLink, RequestContext requestContext)
{
    var startPageContentLink = SiteDefinition.Current.StartPage;

    // Use the content link with version information when editing the startpage,
    // otherwise the published version will be used when rendering the props below.
    if (currentContentLink.CompareToIgnoreWorkID(startPageContentLink))
    {
        startPageContentLink = currentContentLink;
    }

    var startPage = _contentLoader.Get<StartPage>(startPageContentLink);
    var currentPage = _contentLoader.Get<SitePageData>(currentContentLink);

    var model = new LayoutModel
    {
        Logotype = startPage.SiteLogotype,
        AlternativeLogotype = currentPage.AlternativeLogo.GetContent() as SiteLogotypeBlock,
        GoogleTagManager = startPage.GoogleTagManager,
        LogotypeLinkUrl = new MvcHtmlString(_urlResolver.GetUrl(SiteDefinition.Current.StartPage)),
        AdditionalNavigationItems = startPage.AdditionalNavigationItems ?? new EPiServer.SpecializedProperties.LinkItemCollection(),
        Footer = startPage.FooterBlock,
        LoggedIn = requestContext.HttpContext.User.Identity.IsAuthenticated,
        MarketPlaceUrl = startPage.MarketPlaceLink.GetContent() as GeneralLinkBlock,
        LoginUrl = new MvcHtmlString(UrlResolver.Current.GetUrl(startPage.LoginPageLink)),
        SearchActionUrl = new MvcHtmlString(UrlResolver.Current.GetUrl(startPage.SearchPageLink)),
        IsInReadonlyMode = _databaseMode.DatabaseMode == DatabaseMode.ReadOnly
    };

    SetCountriesAndLanguages(GetLanguageVersions(currentContentLink, startPage), model);

    var cookie = requestContext.HttpContext.Request.Cookies[Global.CookieNames.CookiesDisclaimerViewed];

    if (cookie == null || cookie.Value.Equals(bool.FalseString))
    {
        SetCookieDisclaimer(model, startPage);

        requestContext.HttpContext.Response.Cookies.Add(
            new HttpCookie(Global.CookieNames.CookiesDisclaimerViewed, bool.TrueString)
            {
                Expires = DateTime.Now.AddYears(1)
            });
    }

    return model;
}

适用控制器:

namespace Example.Site.Controllers
{
    public class VideoPlayerBlockController : BlockController<VideoPlayerBlock>
    {
        public override ActionResult Index(VideoPlayerBlock currentContent)
        {            
            return PartialView(new VideoPlayerViewModel(currentContent));
        }
    }
}

风景:

@model VideoPlayerViewModel

<section>
    <div class="container">
        <div class="row">
            <div class="embed-responsive embed-responsive-16by9">
                <iframe class="embed-responsive-item"
                        src=@Model.VideoURL
                        frameborder="0"
                        allow="autoplay; encrypted-media"
                        @Model.AllowFullScreen></iframe>
            </div>
        </div>
    </div>
</section>

VideoPlayerViewModel.cs:

using Example.Site.Models.Blocks;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;

namespace Example.Site.Models.ViewModels
{
    public class VideoPlayerViewModel
    {
        private const string YouTubeLink = "https://www.youtube.com/embed/";

        private const string YouTubeNoCookieLink = "https://www.youtube-nocookie.com/embed/";

        private const string StartAtParameter = "start=";

        private const string ShowVideoSuggestionsParameter = "rel=0";

        private const string PlayerControlsParameter = "controls=0";

        private const string TitleAndPlayerActionsParameter = "showinfo=0";

        private const string AllowFullscreenParameter = "allowfullscreen";

        private const string DontAllowFullscreenParameter = "donotallowfullscreen";

        //private const string VideoWidth = "width=";

        //private const string VideoHeight = "height=";

        public string VideoURL { get; set; }

        public string AllowFullScreen { get; set; }

        public VideoPlayerViewModel(VideoPlayerBlock videoBlock)
        {
            AllowFullScreen = videoBlock.AllowFullScreenMode ? AllowFullscreenParameter : DontAllowFullscreenParameter;

            Uri uri = new UriBuilder(videoBlock.YouTubeLink).Uri;
            var queryDictionary = HttpUtility.ParseQueryString(uri.Query);
            var filmCode = queryDictionary.HasKeys() ? queryDictionary["v"] : uri.Segments[1];
            StringBuilder builder = new StringBuilder(videoBlock.EnablePrivacyEnhancedMode ? YouTubeNoCookieLink : YouTubeLink).Append(filmCode);

            var parameters = new List<string>();

            if (!string.IsNullOrEmpty(videoBlock.StartAt) && !Regex.IsMatch(videoBlock.StartAt, "^[0]?[0][:][0]{2}$"))
            {
                var timeString = videoBlock.StartAt.Split(':');
                if (Int32.TryParse(timeString[0], out var minutes) && (Int32.TryParse(timeString[1], out var seconds)))
                {
                    parameters.Add(StartAtParameter + (minutes * 60 + seconds).ToString());
                }
            }

            //if (videoBlock.CustomVideoWidth > 1 && videoBlock.CustomVideoWidth < 100)
            //{
            //    parameters.Add(VideoWidth + videoBlock.CustomVideoWidth);
            //}

            if (!videoBlock.ShowVideosSuggestions)
            {
                parameters.Add(ShowVideoSuggestionsParameter);
            }

            if (!videoBlock.ShowPlayerControls)
            {
                parameters.Add(PlayerControlsParameter);
            }

            if (!videoBlock.ShowTitleAndPlayerActions)
            {
                parameters.Add(TitleAndPlayerActionsParameter);
            }

            if (parameters.Any())
            {
                builder.Append("?" + parameters[0]);
            }

            foreach (var parameter in parameters.Skip(1))
            {
                builder.Append("&" + parameter);
            }

            VideoURL = builder.ToString();
        }
    }
}

有什么问题,我该如何解决?

标签: c#visual-studioepiserver

解决方案


由于某种原因,您的BlockData内容正在由需要模型为 type 的视图呈现SitePageData。换句话说,您似乎正在渲染一个带有页面视图的块。

但由于它在编辑模式下失败,您可能只是缺少块类型的预览渲染器,即控制块如何在页面编辑模式下自行渲染的视图。

块预览是否适用于其他块类型?

编辑模式下块预览的详细信息:https ://world.episerver.com/documentation/developer-guides/CMS/rendering/preview-rendering-for-blocks/


推荐阅读