// get page instance
PageData page = DataFactory.Instance.GetPage(new PageReference(id));
page.Property["Title"].Value = "here comes some new value!!!";
// save and publish
DataFactory.Instance.Save(page, SaveAction.Publish);
Looks nice and easy ... but there is one problem ... it throws an System.NotSupportedException saying that "The property Title is read-only."
You can use DataFactory.Instance.GetPage() method to load pages but EPiServer 5 will return read-only instance of the page. Compiler will not complain that you are assigning new value to the read-only property but in a runtime you will get the exception. If your goal is to update a page you should use this method to get modifiable instance: PageData.CreateWritableClone()
and it whole should looks like that:
// get read-only page instance
PageData readonlyPage = DataFactory.Instance.GetPage(new PageReference(id));
// get modifiable instance
PageData modifiablePage = readonlyPage.CreateWritableClone();
modifiablePage.Property["Title"].Value = "here comes some new value!!!";
// save and publish
DataFactory.Instance.Save(modifiablePage, SaveAction.Publish);
Why EPiServer 5 forces us to write this one extra line of code? Answer is performance! Returning read-only instances is significantly faster and moreover ... in most cases that is what you really need. I guess that in 90% of cases you are accessing data simply to display it for the users. In the rest, 10% cases, you want to update those data. It makes perfect sense to have it working faster in typical cases and to write one additional line of code when you want to modify properties.
5 comments:
Interesting. As a complete novice to Episerver, help me out here, when a page is cached, are all the properties associated with that page read-only as well?
As a developer, I would expect to see a nice convenience method would be not to have to worry about that extra line of code. With that in mind, can I have something like:
UpdateProperty(pageId, propertyName, newValue)
Then inside this method, can I ask the property if it is modifiable (with catching NotSupportedException), for example:
Property[propertyName].IsModifiable
and then this method takes care of all this for me (as well as returning the oldValue from the method :-) ).
Is this possible?
Hi Cleve, answer is yes, it’s possible.
EPiServer API provides means to get all information which you need. PageData and PropertyData classes have IsReadOnly public property. So when you call DataFactory.Instance.GetPage() metod then returned PageData object will have this property set to true. Of course all properties (PropertyData objects) associated with the page will also have this property set to true.
You can then call PageData.CreateWritableClone() which will return new instance of the same page, but this time the IsReadOnly properties (on PageData and PropertyData objects) will be set to false. And at this point you are free to modify whatever you want.
Hope it answers your question :)
It does. Thanks Marek.
I was just thinking whether such convenience methods come with the framework, or whether at this point in time we build them? Sounds like we have the means to build them.
Thank you, this is a fantastic post and has been very helpful.
This is a greeat post thanks
Post a Comment