What version are you using? Helps to determine if it is a bug or not.
Where are these CustomContent located? What ContentProvider is used?
This project is on version 11.3.0 (sorry, thought I included that in my original post). I am using the default ContentProvider. I'm essentially doing what this blog post is describing. It seems strange that everything works as expected when setting a property other than Name.
Somewhere in the back of my head there is a notion we reported a bug that it doesn't save if only the name is changed, but i thought it had been fixed already. Of course when i go in search of it now i can't find it. :(
Is this something I should try to file a bug for then? I can hack a workaround together (add a second, duplicated "name" property), but I'd rather it just work as intended...
Yes file a bug with Episerver development support, worst case scenario they will tell you in what version it has been fixed in. :D
When you set the value of a property, ContentData.IsModified is set to true. The exception is the properties on IContent which doesn't trigger a change to IsModified. So in your example, IsModified is false both before and after setting customContent.Name = "Test Name" but will be true after customContent.Test = "Test". The data access layer will determine if a content needs to be saved based on IsModified.
Solution, implement IContent properties with something like:
private string _name; public string Name { get { return _name; } set { if (!string.Equals(value, _name)) { _isModified = true; _name = value; } } } private bool _isModified; public bool IsModified { get { return _isModified; } } public void ResetModified() { _isModified = false; }
You can also inherit from BasicContent instead of ContentData which has this implememented.
Post edited to also include the implementation of IModifiedTrackable.
Interesting. Inheriting from BasicContent does indeed make things work as expected. I never would have thought to implement my own "is dirty" tracking on a property, but I guess the IContent properties must be treated differently than other, custom properties (which explains why the "Test" property worked as expected).
Everything I've seen (tutorials, etc.) demonstrates inheriting from ContentData. In fact, I'm pretty sure that was even mentioned in the training/bootcamp. The documentation could certainly use some clean up when it comes to using custom IContent. Anyway, I decompiled EPiServer.dll and took a look at the EPiServer.Core namespace, and I think I figured out what each of the various "base classes" for content are meant to do:
I noticed some strangeness when saving custom pieces of IContent, and I'm not sure if I've stumbled onto a bug, or if I misunderstand how this should work. When I create a piece of IContent, and try to set the "Name" property (nothing else), the value does not persist when calling ContentRepository.Save().
For example, if I have the following custom IContent:
And then try to save it:
The name property does not persist after calling save. However, it works as expcted if I change the code so that the "Test" property that is defined on CustomContent is also set (instead of just the name):
The above code is simplified. In my actual implementation, I have a custom ContentRepositoryDescriptor and NavigationComponent wired up to allow editing the custom IContent in the UI. The UI performs similarly when modifying an existing receord: "Name" doesn't even trigger the "is modified" logic to allow publishing.
Is this a bug, or am I missing something?