November Happy Hour will be moved to Thursday December 5th.

Content Delivery API: render any block inside XhtmlString property

Vote:
 

Hi everyone,

Our team is building a single-page application retrieving content from EPiServer Content Delivery API. A key requirement from the editors is that they should be able to use blocks inside XhtmlString properties (TinyMCE text editor). We're having trouble getting content from blocks included in XhtmlString properties in our API's reponses.

We have tried combining the steps in the two following articles in order to override the default serialization of XhtmlString properties and render the blocks inside them by using EPiServer's "RenderXhtmlString" extension method for HtmlHelper instances.

  1. https://talk.alfnilsson.se/2018/04/24/tweaking-and-extending-serialization-from-episerver-content-delivery-api/
  2. https://antecknat.se/blog/2016/03/07/xhtmlstring-render-blocks-and-convert-link-to-external-without-htmlhelper/

Here are snippets of our code:

Custom property model for XhtmlString

    public class CustomXhtmlStringPropertyModel : PropertyModel<XhtmlString, PropertyXhtmlString>
    {
        public CustomXhtmlStringPropertyModel(PropertyXhtmlString propertyXhtmlString) : base(propertyXhtmlString)
        {
            ExternalValue = propertyXhtmlString.XhtmlString.ConvertToExternal();
        }

        public string ExternalValue { get; set; }
    }

Extension method "ConvertToExternal"

        public static string ConvertToExternal(this XhtmlString xhtmlstring)
        {
            if (string.IsNullOrWhiteSpace(xhtmlstring?.ToHtmlString()) || xhtmlstring.IsEmpty)
            {
                return string.Empty;
            }
            var routeData = new RouteData();
            routeData.Values.Add("controller", "a");
            routeData.Values.Add("subject", "a");

            var hh = new HtmlHelper(new ViewContext()
            {
                HttpContext = new HttpContextWrapper(HttpContext.Current),
                ViewData = new ViewDataDictionary(),
                TempData = new TempDataDictionary(),
                Controller = new DummyController(),
                RouteData = routeData
            }, new ViewPage());


            string result;
            using (var writer = new StringWriter())
            {
                hh.ViewContext.Writer = writer;
                hh.RenderXhtmlString(xhtmlstring);
                writer.Flush();
                result = writer.ToString();
            }
            return result;
        }

The extension method "ConvertToExternal" works as expected (by including content for blocks inside the XhtmlString) when using it in a traditional ASP.NET MVC EPiServer solution. However, it does not include any content from blocks when being used through EPiServer's Content Delivery API.

Any suggestion as to what we are doing wrong, or other solutions to our problem, is much appreciated.

- Thomas

#206361
Edited, Aug 16, 2019 13:24
Vote:
 

Your extension method looks quite similar to the method XhtmlRenderService.RenderXHTMLString(params) and it should work by default.

Which ContentDeliveryApi version are you using ?

#206466
Aug 22, 2019 5:41
Vote:
 

Hi Quan,

Thanks for the reply.

We're using version 2.6.1 of the ContentDeliveryApi packages.

After troubleshooting some more, we found out that the block we were using in our XhtmlString property didn't have a corresponding view defined. That explains why the block's content didn't render in the response. Using a block having a corresponding view worked even without the custom property model.

- Thomas

#206476
Aug 22, 2019 8:38
Vote:
 

Nice, Thomas.

#206481
Aug 22, 2019 10:19
This topic was created over six months ago and has been resolved. If you have a similar question, please create a new topic and refer to this one.
* 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.