1717130001
2024-05-30 09:36:01
まとめ
レンダリングを有効にするには ブレザー Optimizelyのコンポーネント .NET 8 上の CMS 12: コピー カスタムプロパティレンダラー 以下のクラスをプロジェクトに追加し、組み込みの プロパティレンダラー クラス。
問題
Blazor コンポーネントを多用する Optimizely CMS 12 ソリューションを .NET 8 にアップグレードした後、次の例外が発生しました。
The current thread is not associated with the Dispatcher. Use InvokeAsync() to switch execution to the Dispatcher when triggering rendering or component state.
この例外自体は、Blazor コンポーネント自体とは関係なく、Optimizely がプロパティをレンダリングする方法に問題があるため、やや誤解を招くものです。
ソリューション
以下をコピー カスタムプロパティレンダラー クラスをプロジェクトに追加します:
using EPiServer.Web.Mvc;
using EPiServer.Web.Mvc.Html;
using Microsoft.AspNetCore.Html;
using Microsoft.AspNetCore.Mvc.Rendering;
using System.Text.Encodings.Web;
public class CustomPropertyRenderer : PropertyRenderer
{
///
/// Replaces the internal class .
///
/// Instead of implementing we inherit to ensure proper rendering of Blazor components.
private class WrappedHtmlContent : HtmlContentBuilder
{
public WrappedHtmlContent(IHtmlContent content) => AppendHtml(content);
public override string ToString()
{
using StringWriter stringWriter = new();
WriteTo(stringWriter, HtmlEncoder.Default);
return stringWriter.ToString();
}
}
///
/// Exact copy of method from , except for the use of our custom class.
///
protected override IHtmlContent GetHtmlForEditMode(IHtmlHelper html, string viewModelPropertyName, object editorSettings, Func displayForAction, string templateName, string editElementName, string editElementCssClass, RouteValueDictionary additionalValues)
{
var _editHintResolver = html.ViewContext.HttpContext.RequestServices.GetRequiredService();
if (!_editHintResolver.TryResolveEditHint(html.ViewContext, viewModelPropertyName, out var contentDataPropertyName))
{
if (!CurrentContentContainsProperty(html, viewModelPropertyName))
{
return new WrappedHtmlContent(displayForAction(templateName));
}
contentDataPropertyName = viewModelPropertyName;
}
HtmlContentBuilder htmlContentBuilder = new();
using (CreateEditElement(html, "data-epi-property-name", contentDataPropertyName, editElementName, editElementCssClass, () => CustomSettingsAttributeWriter(additionalValues, "data-epi-property-rendersettings"), () => CustomSettingsAttributeWriter(new RouteValueDictionary(editorSettings), "data-epi-property-editorsettings"), htmlContentBuilder))
{
htmlContentBuilder.AppendHtml(displayForAction(templateName));
}
return new WrappedHtmlContent(htmlContentBuilder);
}
///
/// Exact copy of method from , except for the use of our custom class.
///
protected override IHtmlContent GetHtmlForDefaultMode(string propertyName, string templateName, string elementName, string elementCssClass, Func displayForAction)
=> new WrappedHtmlContent(displayForAction(templateName));
}
内蔵の プロパティレンダラー 入力する カスタムプロパティレンダラー あなたの 起動する クラス:
services.AddTransient();
詳細情報
これ ワールドのフォーラム投稿 問題とその再現方法をわかりやすく説明しています。ありがとう、Kevin!
リンク先は GitHub リポジトリ Optimizely のサンプル サイトでは、不具合のある動作が見られます。
この問題はOptimizelyの内部クラスに起因している。 ラップされた HTML コンテンツ これは本当に基本的な実装です IHTMLコンテンツ。
Blazorコンポーネントのレンダリングをサポートするために、 IHTMLコンテンツ 実装はバッファリングされる必要があり、.NET 8は内部のシールを介してそれを実行します ビューバッファ クラス。
以来 ビューバッファ 実装する IHTMLコンテンツビルダーOptimizelyの ラップされた HTML コンテンツ クラスを継承するようにした HTMLコンテンツビルダー 実装する代わりに IHTMLコンテンツ 。
この問題はいずれ Optimizely によって解決されると予想されますが、それまではこれが有効な回避策であると思われます。
#Optimizely #CMS #の #Blazor #と #.NET