There are times where we need to programatically either create or update a Sitecore item. Sitecore is very flexible and through their API this is possible.
When altering items through the API you need to consider, which database you want to alter the item in. Normally this should happen in master database like for example when developing an import process. This is the scenario that I will cover in this post. First I am going to show you how to use the API directly and then I am going to show you how to do this using GlassMapper objects.
The traditional way to update a Sitecore item would be through the Sitecore API doing something like this:
//Use a security disabler to allow changes
using (new Sitecore.SecurityModel.SecurityDisabler())
{
//You want to alter the item in the master database, so get the item from there
Database db = Sitecore.Configuration.Factory.GetDatabase("master");
Item sitecoreItem = db.Items["/sitecore/content/home"]; //Open the editing state sitecoreItem.Editing.BeginEdit();
try {
//perform the editing
sitecoreItem.Fields["MyProperty"].Value = "This is the updated value";
}
finally
{
//Clossing the editing state
sitecoreItem.Editing.EndEdit();
}
}
After we run this code the MyProperty property value will change.
As you may know, Glassmapper is a very popular and robust ORM. You can work in code with the classes that are representing the Sitecore templates. This makes the interaction between Sitecore items and code more natural.
As you noticed we used the Sitecore API directly in the sitecoreItem object, we didn't use GlassMapper ORM.
Now lets do the same thing with GlassMapper.
sitecoreItem.MyProperty = "This is the updated value";
try
{
using (new SecurityDisabler())
{
SitecoreServiceMaster.Save(sitecoreItem);
}
}
catch (Exception exception)
{
Log.Warn($"Failed to update Job item {sitecoreItem.id} : {exception.Message}", exception, this);
return false;
}
Using GlassMapper for updating values is very straightforward, the code is simpler since we can use an object from the Sitecore template to acomplish our needs. We ended up accessing directly to the MyProperty value, then using the SitecoreService we updated the value into the Master database.
Until now everything seems very simple with GlassMapper until you have to update an Rich Text Field (RTF) property. If you try to update an RTF property using the same approach you will get an error, telling you that to edit and RTF property you need to access the raw value of it.
The error says:
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 SitecoreDemo.Models.sitecore.templates.SitecoreDemo.Testing.Items.IMyRtfProperty
After some research I was able to identify what is happening. Because of an implementation decision from Glasmapper creator (Michael Edwards) there is a restriction to update RTF properties (see the end of this post). Although there is a simple way to make it work too.
The declaration of RTF fields in the classes needs to have the following annotation to be able to edit it in code.
[SitecoreField("MyRtfProperty", Setting = SitecoreFieldSettings.RichTextRaw)]
public virtual string MyRtfProperty {get; set;}
The setting SitecoreFieldSettings.RichTextRaw is the one that let us use this property as raw property, therefore it allow us to make changes in it. After this, changes made to RTF properties follow the same pattern as in the previous GlassMapper example.
There is a reason why GlassMapper creator did this, it is to allow easy rendering and allow Experience Editor capabilities in the view when resolving RTF properties.
If you need to edit RTF properties I would suggest declaring the property twice, one for regular use and one for update/save motives. Something like this: