Prevent saving properties in sitecore with custom validator in C#
Recently I had a requirement that when under certain conditions a Sitecore field should become readonly. To accomplish this requirement I created a new ReadOnlyWhenXYZValidator
. The requirement stated that the validator should stop a user from saving the item if the field had changed. Here is how I accomplished it.
What I decided to do was create a custom validator that can be applied to each property that should become readonly once a condition is met.
[Serializable]
public class ReadOnlyWhenXYZValidator : StandardValidator
{
public ReadOnlyWhenXYZValidator()
: base()
{
}
public ReadOnlyWhenXYZValidator(SerializationInfo info, StreamingContext context)
: base(info, context)
{
}
public override string Name
{
get {
return Sitecore.StringUtil.GetString(this.Parameters["ValidatorName"],
this.GetType().ToString()); }
}
protected override ValidatorResult GetMaxValidatorResult()
{
return GetFailedResult(ValidatorResult.Error);
}
protected override ValidatorResult Evaluate()
{
Item item = this.GetItem();
// The following will need to be replaced with your own logic to
// retrieve if an item should be readonly...
var isReadOnly= ShouldBeReadOnly(item.ID.Guid);
if (isReadOnly)
{
bool propertyHasChanged = HasPropertyChanged();
if (propertyHasChanged)
{
this.Text = String.Format(
"Field '{0}' is readonly and cannot be updated",
this.GetFieldDisplayName());
// Fatal Error is required in order to prevent saving
return ValidatorResult.FatalError;
}
}
this.Text = "Valid";
return ValidatorResult.Valid;
}
/// <summary>
/// Returns a value indicating if the property value has changed
/// </summary>
private bool HasPropertyChanged()
{
var value = GetControlValidationValue();
var contentItem = Sitecore.Context.ContentDatabase.GetItem(GetItem().ID);
if (contentItem == null)
{
return false;
}
var oldValue = contentItem[GetField().ID];
//Check if current value is different from an old value
return value != oldValue;
}
}
Notice I am returning a ValidatorResult.FatalError
. This is the only ValidatorResult
that prevents a user from saving an item, so although it sounds over the top, is required.
Once complete, simply tell Sitecore to run the validator against the fields you wish to validate. This is done by firstly adding a new Validation Rule to System > Settings > Validation Rules > Field Rules
or a sub folder of that.
Once added, simply navigate to your field definitions and, within the Validation Rules
section, add your custom validator to each of the folllowing:
- Quick Action Bar
- Validate Button
- Validator Bar
- Workflow
Once complete load your items and you should find you can't save items that match the condition you have. I hope this helps. Don't forget to share this article if you found it helpful.
I have tried this but data is saving. I want that when validation give error than data should not save. It should be abort save state.
Hi Pravinkumar,
Providing the validator is returning ValidatorResult.FatalError
then sitecore determines that this will prevent saving. Could it be possible that the result is not a FatalError
.
Thanks John: I have solve first problem. One more point is that . I want to get new value of field in class file EX : Suppose I have on date filed . I am going to change from 03 Apr to 05 Apr . in that case i want to get 05 Apr value in my class file. It is possible
I have used Item validation.
I am trying to compare start date and end date field validation .
Pls help me if possible
thanks you in advance
Hi Pravinkumar,
Glad to help. You can use GetControlValidationValue();
to get the new value that has been set (05 Apr). For reference, take a look at the HasPropertyChanged()
method above.
Hi John : I already used you technique. but problem is that. I got null value. Here I want to two filed (new value) StartDate and EndDate. then after I will compare both.
------------------ Example -----------------
Sitecore.Data.Items.Item item = this.GetItem(); string firstFieldName = Sitecore.StringUtil.GetString(this.Parameters["FirstFieldName"], "StartDate"); string lastFieldName = Sitecore.StringUtil.GetString(this.Parameters["LastFieldName"], "EndDate"); Sitecore.Data.Fields.DateField first = item.Fields[firstFieldName]; Sitecore.Data.Fields.DateField last = item.Fields[lastFieldName];
here I have got old value
I want New updated value which is not saved in DB
Hi Pravinkumar,
This particular validator is not able to validate other pre-saved field values unfortunately.
ok Many Many thnxxx
John, do you know how to display some sort of message on the dialog that prevents users from saving the message in the content editor? "This item contains fields with fatal errors." isn't super helpful.