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?
The Field
object has properties indicating this, such as ContainsStandardValue
, ContainsFallbackValue
, InheritsValueFromOriginalItem
, 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?
Update:
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 __Standard values
:
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.
field.ContainsStandardValue
property, it'd expect it to be true. And it usually is. But if some other code, such as another processor, has calledfield.GetValue(false)
prior my code, the property would read false. So the values of those properties are inconsistent.GetValue()
method is called with the expected arguments.