I guess I somewhat know the answer, but I'd like to get the community feedback on this.
What is the correct way of identifying where a field value originates from? When
item.Fields[field].HasValue is false, the
Value property contains a fallback value. I want to know what kind of fallback value it is. Is it the default value (the shared field on the template field item), is it from
__Standard values, is it a language fallback value or is it from a clone source item?
Field object has properties indicating this, such as
IsValidForLanguageFallback and so on. Now, it turns out that those properties are actually modified when you call the
field.GetValue() methods, and their values becomes different depending on what argument you pass to the
field.GetValue(bool allowStandardValue, bool allowDefaultValue, bool allowFallbackValue, bool allowInheritValue, bool allowInnerValue) (or any of its shorter alternatives). This feels like an error in the implementation to me.
Is there a more solid, reliable or preferred way of getting this information, other than always calling
field.GetValue(true, false, true) prior reading any of those fallback properties on the field?
As Mark pointed out in the comments, the issue here is that the properties "remember" the states of the last
GetValue call. Here's a sample to illustrate this:
Let's say there is an item with a Title-field, with a
null value, so the shown value is taken from
var field = item.Fields["Title"]; var title = field.Value; var stdValue = field.ContainsStandardValue; // becomes true title = field.GetValue(false); stdValue = field.ContainsStandardValue; // now becomes false
So, the value of these properties are based on the last call to
GetValue(), that could be code from another processor etc.