AI OnAI Off
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;
}
}
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.
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.
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.