Five New Optimizely Certifications are Here! Validate your expertise and advance your career with our latest certification exams. Click here to find out more

How to avoid duplicates of contents in a ContentArea

Vote:
 

Is there an easy way to avoid duplicates in the ContentArea?

Have searched but not found much.... I prefer not to hook up in publish event att do the check myself..

Attribute like [DisableDuplicates] would have been perfect here

#147526
Apr 18, 2016 10:49
Vote:
 

How about creating a custom validator for this? You could either give a warning or an error message to the editors.

http://henrikm.com/custom-episerver-property-validation/

#147528
Apr 18, 2016 11:01
Vote:
 

Yes, I tried it and it works perfectly!!

Thanks a lot, this made my day :)

A minor thing... would be great to be able to present the actual proprerty display name to the editor (and not the actual property name)...

#147529
Apr 18, 2016 11:27
Vote:
 

Great! 
Regarding the display name, you could check out Grzegorz answer in this forum thread: http://world.episerver.com/forum/developer-forum/Developer-to-developer/Thread-Container/2015/8/localized-property-name-in-validation/

#147530
Apr 18, 2016 11:48
Vote:
 

Yes I found his answer and borrowed it :-)

Here is the code if anyone is interested, not many rows

[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]
	public sealed class DisableDuplicates : ValidationAttribute
	{
		protected override ValidationResult IsValid(object value, ValidationContext validationContext)
		{
			var propertyDefinitionRepository = EPiServer.ServiceLocation.ServiceLocator.Current.GetInstance<IPropertyDefinitionRepository>();
			var propertyDefinitionId = ((PageData)validationContext.ObjectInstance).Property[validationContext.MemberName].PropertyDefinitionID;
			var propertyDefinition = propertyDefinitionRepository.Load(propertyDefinitionId);
			propertyDefinition.LocalizationService = LocalizationService.Current;

			if (IsDuplicate(value as ContentArea))
			{
				return new ValidationResult(
					$"You can not have duplicate content in: '{propertyDefinition.TranslateDisplayName()}'",
					new[] { validationContext.MemberName });
			}

			return ValidationResult.Success;
		}

		bool IsDuplicate(ContentArea area)
		{
			if (area == null || area.IsEmpty)
				return false;

			if (area.Items == null || area.Items.Any() == false)
				return false;

			List<int> items = new List<int>();

			foreach (var cai in area.Items)
			{
				if (items.Contains(cai.ContentLink.ID))
					return true;

				items.Add(cai.ContentLink.ID);
			}

			return false;
		}
	}
#147531
Apr 18, 2016 11:49
Vote:
 

Thanks for sharing! :-)

#147534
Apr 18, 2016 11:53
Vote:
 

Sounds like a good solution. I might steal it :)

#147537
Apr 18, 2016 12:10
Vote:
 

You could also simplify IsDuplicate method to single line expression :)

private bool IsDuplicate(ContentArea area)
{
    return area?.Items.DistinctBy(c => c.ContentLink.ToReferenceWithoutVersion()).Count() != area?.Items.Count;
}
#147545
Apr 18, 2016 13:24
Vote:
 

Excellent!

#147548
Apr 18, 2016 13:44
This topic was created over six months ago and has been resolved. If you have a similar question, please create a new topic and refer to this one.
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.