Glass.Mapper.Sc | It is not possible to save data from a rich text field when the data isn’t raw

While the Sitecore API allows you to create, update and delete content in Sitecore, I find it to be easier to use the Glass.Mapper.Sc.ISitecoreService to do this.  Mike Edwards has a great tutorial on how to use the ISitecoreService, http://www.glass.lu/Mapper/Sc/Documentation/ISitecoreService.  I strongly encourage everyone who’s using Glass in your projects to take a look at Mike’s ISitecoreService and consider using the methods in it instead of the Sitecore API.

This post is about an error you will get when inserting content into Sitecore using the ISitecoreService if one or more of the fields being populated are rich-text fields.  Here’s the error:

It is not possible to save data from a rich text field when the data isn’t raw.Set the SitecoreFieldAttribute setting property to SitecoreFieldSettings.RichTextRaw for property Description on type ScWebApi.Domain.Models.sitecore.templates.ScWebApi.Shared_Content.Items.IProduct

I reached out to Mike on the Sitecore Slack #glass room and he knew exactly what my problem was and enlightened me to the fact that if you’re saving a Glass object that has a property that maps to a rich-text field, you need that property to be decorated in one of two ways:

  1. set ReadOnly = true
    [SitecoreField("Body Content", ReadOnly = true)]
    string Body_Content { get; set; }
  2. set Setting = SitecoreFieldSettings.RichTextRaw
    [SitecoreField("Body Content", Setting = SitecoreFieldSettings.RichTextRaw)]
    string Body_Content { get; set; }

Keep Reading!

While both of these solutions resolve the error I mentioned above, both solutions have their own considerations:

  1. if you set ReadOnly = true, you cannot set the field when you are trying to insert content into Sitecore
  2. if you set Setting = SitecoreFieldSettings.RichTextRaw, this property will not support Experience Editor when you are trying to render it with @Editable() in your rendering

Solution

The best way I’ve found to deal with this error is to actually have two properties that map to the same rich-text field:

[SitecoreField("Body Content", ReadOnly = true)]
string Body_Content { get; set; }

[SitecoreField("Body Content", Setting = SitecoreFieldSettings.RichTextRaw)]
string Body_Content_Raw { get; set; }

The first property is the one you’ll use in your renderings so that you can have Experience Editor support.  The second property is the one you’ll use in your code where you’re setting the value of the field before inserting or updating the item in Sitecore.

TDS

If you’re generating your models using TDS, you’ll need to update your glassv3item.tt T4 template to generate the two properties for rich-text fields.  I’ve forked Mike’s glassv3item.tt T4 template on Github and updated it to generate the two properties as I’ve shown above for rich-text fields and you can download it here:

https://github.com/dcouto/tds-codegen/blob/master/Sitecore.Master/Code%20Generation%20Templates/GlassV3Item.tt

2 thoughts on “Glass.Mapper.Sc | It is not possible to save data from a rich text field when the data isn’t raw

  1. We choose this implementation because we wanted the Rich Text data to be in a format that could be rendered without any additional code needing to be written, so this would work:

    @Model.Body_Content

    To do this we have to send the Rich Text field through the render field pipeline. This correctly formats the links and images for rendering. If we allowed you to then save this back to Sitecore it would cause lots of internal problems with Sitecore, e.g. the page editor, link table, etc.

    Therefore we use the RichTextRaw flag to indicate that you intend to use the field for writing data to Sitecore and therefore we should not call the Render Field pipeline.You should never use the RichTextRaw flag with a property that will be used for rendering.

    I personally would prefer to have two models, one that is used for rendering and doesn’t have the RichTextRaw flag and then another model that is used for writing data to Sitecore.

    • Doug on

      Makes complete sense, Mike. I agree with your approach of having two models with one property in each instead of one model with two properties and that would be very straight-forward to do if you’re writing your Glass objects by hand. But if you’re using TDS to generate them, based on my limited knowledge of what you can do in a T4 template, that might be a little harder to script out.

      The only way I can think of doing it would be to loop over every field and if any were a rich-text field, generate the model twice but in that loop, you’d need to generate one model with the normal property and another model with the RichTextRaw property. Maybe there’s an easier way to do this with the TDS T4 templates.

Leave a Reply