Cannot get raw html result from Custom ContentAreaRenderer

Vote:
 

I'm trying to add some custom attribute while content area rendering depend on httpContext.

Created custom content area renderer but I get Microsoft.AspNetCore.Mvc.Rendering.TagBuilder+RenderTagHtmlContent at both start and end.

protected override void RenderContentAreaItem(IHtmlHelper htmlHelper, ContentAreaItem contentAreaItem,string templateTag, string htmlTag, string cssClass)
{
            var originalWriter = htmlHelper.ViewContext.Writer;
            var tempWriter = new StringWriter();
            
            htmlHelper.ViewContext.Writer = tempWriter;
            var content = contentAreaItem.InlineBlock;
            
            base.RenderContentAreaItem(htmlHelper, contentAreaItem, templateTag, htmlTag, cssClass);
            
            // Content having TagBuilder issues here
            var contentItemContent = tempWriter.ToString();
}

Seem base.RenderContentAreaItem from Epi packages having issue with tagBuilder

protected virtual void RenderContentAreaItem(IHtmlHelper htmlHelper,ContentAreaItem contentAreaItem,string templateTag,string htmlTag,string cssClass)
{
//....
using (new ContentRenderingScope(htmlHelper.ViewContext.HttpContext, contentData, templateModel, templateTags))
{
        TagBuilder tagBuilder = new TagBuilder(htmlTag);
        this.AddNonEmptyCssClass(tagBuilder, cssClass);
        tagBuilder.MergeAttributes<string, string>(this._attributeAssembler.GetAttributes(contentAreaItem, this.IsInEditMode(), templateModel != null));
        this.BeforeRenderContentAreaItemStartTag(tagBuilder, contentAreaItem);
        // I think we should write tagBuilder string result here
        htmlHelper.ViewContext.Writer.Write((object) tagBuilder.RenderStartTag());
        htmlHelper.RenderContentData(contentData, true, templateModel, this._contentRenderer);
        // and here
        htmlHelper.ViewContext.Writer.Write((object) tagBuilder.RenderEndTag());
}
//...
}

Does anyone have work around solution, please advise.

#297613
Mar 03, 2023 8:02
Vote:
 

What are you trying to achieve exactly?  There have been other questions with answers recently where developers have removed both the <div> tags that surround the content area and <div> tags that surround each individual block.  This would then allow you to control the markup 100% from the razor files for the individual blocks.

#297628
Mar 03, 2023 8:57
Vote:
 

Hi @Mark Stott,

I'm having some custom ViewData variables, passed it to RenderContentAreaItem via .PropertyFor func in razor. In there I need bind ViewData variables as div attributes to content area render result. With CMS 11.x I can parse context writer result to html dom and do anything with that, when trying with cms 12, stucking with TagBuilder :(

protected override void RenderContentAreaItem(IHtmlHelper htmlHelper, ContentAreaItem contentAreaItem,string templateTag, string htmlTag, string cssClass)
{
            var originalWriter = htmlHelper.ViewContext.Writer;
            var tempWriter = new StringWriter();
            
            htmlHelper.ViewContext.Writer = tempWriter;
            var content = contentAreaItem.InlineBlock;
            
            base.RenderContentAreaItem(htmlHelper, contentAreaItem, templateTag, htmlTag, cssClass);
            
            // Content having TagBuilder issues here
            var contentItemContent = tempWriter.ToString();
            // Parse contentItemContent to html dom and do anything here - with CMS 12 - having TagBuilder issue 
}
#297637
Mar 03, 2023 9:31
Vote:
 

Before I try and replicate the issue you're having, have you recently updated your visual studio and is this a symptom of Microsoft breaking the tag helpers as per this article:

https://world.optimizely.com/forum/developer-forum/Developer-to-developer/Thread-Container/2023/2/cms12-issue-due-to-upgrade-of--net-runtime-from-7-0-2-to-7-0-3/

#297652
Edited, Mar 03, 2023 11:06
Dzung Nguyen - Mar 06, 2023 2:27
Hi Stott, I'm using .Net 6 latest version and EPiServer.CMS 12.17, I don't think this issue relate with .net version
Vote:
 

Hello Dzung,

I had a look at this and if you are trying to add additional attributes to the container tag for the block based on the http context, then you could look at extending or overwriting the IContentAreaItemAttributeAssembler interface.

public class CustomContentAreaItemAttributeAssembler : IContentAreaItemAttributeAssembler
{
    private readonly IHttpContextAccessor _contextAccessor;

    public CustomContentAreaItemAttributeAssembler(IHttpContextAccessor contextAccessor)
    {
        _contextAccessor = contextAccessor;
    }

    public IDictionary<string, string> GetAttributes(ContentAreaItem contentAreaItem, bool isRenderedInEditMode, bool hasRenderer)
    {
        var httpContext = _contextAccessor.HttpContext;

        return new Dictionary<string, string>
        {
            { "test", "foo" }
        };
    }
}

This will result in this:

<div test="foo">
  <!-- block render gets added here -->
</div>
#297794
Mar 06, 2023 9:23
Vote:
 

Hello @Stott,

Is there any other way add custom attributes, I need to access ViewData to get custom attribute value. In RenderContentAreaItem function I can do it via IHtmlHelper.ViewContext. I'm passing ViewData to ViewContent by bellow way:

@Html.PropertyFor(model=>model.ContentAreaItem, 
          new ViewData() {
                  // All custom attributes need set to Content area block html wrapper
                  "customAttr1" : "attr1_value",
                  "customAttr2" : "attr2_value",
                  "customAttr2" : "attr2_value"
          })
#297907
Mar 08, 2023 4:46
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.