Validate duplicate content on Blocks

Vote:
 

I have a block (VideoBlock) that has a string type named Video (represents video id). I had to prevent users from creating more than one video block with same video id and used below code in Save event. 

if (args.Content is VideoBlock videoBlock)
{
var videoList = _client.Search<VideoBlock>()
.Filter(x => x.Video.Match(videoBlock.Video))
.GetContentResult();

if (videoList.TotalMatching == 0) { return; }
if (videoList.TotalMatching == 1)
{
if (((IContent)videoList.First()).ContentLink.CompareToIgnoreWorkID(((IContent)videoBlock).ContentLink))
{
return;
}
}

args.CancelAction = true;
args.CancelReason = "Video Block already exists";

}

This was working all fine till recently. Now when user tries to create a video block and puts existing Video id, the screen freezes and I don't see anything in the logs. I tried to copy paste an existing block and found below error:

Failed to copy page 'Test Video' to 'Videos'.:Exception: The remote server returned an error: (400) Bad Request. SearchPhaseExecutionException[Failed to execute phase [query], all shards failed; shardFailures.

#222281
May 01, 2020 22:16
Vote:
 

Hi Dileep,

Not sure what is wrong in your code but you can try this code.

    [InitializableModule]
    [ModuleDependency(typeof(EPiServer.Web.InitializationModule))]
    public class PreventDuplicateVideoIdInitializationModule : IInitializableModule
    {
        public void Initialize(InitializationEngine context)
        {
            var events = context.Locate.ContentEvents();
            events.SavingContent += EventSavingContent;
        }

        public void EventSavingContent(object sender, ContentEventArgs eventArgs)
        {
            var contentLoader = ServiceLocator.Current.GetInstance<IContentLoader>();
            var contentTypeRepository = ServiceLocator.Current.GetInstance<IContentTypeRepository>();
            var contentModelUsage = ServiceLocator.Current.GetInstance<IContentModelUsage>();

            var contentType = contentTypeRepository.Load<VideoBlock>();
            var contentUsages = contentModelUsage.ListContentOfContentType(contentType);

            // get distinct content references without version
            var contentReferences = contentUsages
                .Select(x => x.ContentLink.ToReferenceWithoutVersion())
                .Distinct()
                .ToList();

            // fetch data from DB
            var instances = contentReferences
                .Select(contentReference => contentLoader.Get<IContent>(contentReference))
                .ToList();

            // remove unpublished
            new FilterPublished().Filter(instances);

            if (eventArgs.Content is VideoBlock videoBlock)
            {

                bool isVideoIdExist = instances.Any(x =>
                {
                    var b = contentLoader.Get<VideoBlock>(x.ContentLink);
                    return b.VideoId == videoBlock.VideoId;
                });

                if (isVideoIdExist)
                {
                    throw new Exception("Video ID already in use in different block");
                }
            }
        }
        public void Uninitialize(InitializationEngine context)
        {
            var events = context.Locate.ContentEvents();
            events.SavingContent -= EventSavingContent;
        }
    }
#222300
May 02, 2020 3:59
Vote:
 

I think I found the issue. My query to fetch blocks didn't had filterforvisitor so it was looking in trash as well. Not sure why the error instead of validation message but error is not occuring anymore.

Also if any one can provide inputs on which is better, using Epi Find search or contentloader in such circumstances for future references.

#222623
May 08, 2020 13:33
Vote:
 

in CMS edit, Suppose if a page is having multiple blocks of the same type, a specific block property should be unique across all the blocks within the same page. Is there a way we can validate if a block's property is unique across a page? for ex: a buttons ID, to ensure that the ID is not duplicated in the same page.

#225342
Jul 13, 2020 14:39
Praful Jangid - Jul 14, 2020 7:39
I replied to your forum thread :)
https://world.episerver.com/forum/developer-forum/-Episerver-75-CMS/Thread-Container/2020/7/page-level-validation-for-a-block-property-value-in-cms-edit-view/
Let me know if that helps.
* 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.