November Happy Hour will be moved to Thursday December 5th.

Comparing blocks

Vote:
 

Hey all

A customer of mine has a solution where they store their contacts as global blocks (a Contact block). I now need to add custom validation for a couple of fields (name, email) to ensure that they're not already published in previous contacts (ie Contact blocks).

I've tried both using ValidationAttribute and IValidate. I search for existing Contact blocks to see whether name/email exists. The problem is that I can't separate previously published Contact blocks from the one I'm currently editing, which in the end always result in a validation error (name/email already exists). So for instance, if I create a new block and type in a name that isn't used anywhere, I get a validation error which originates from the new block.

Example code:

var contentTypeRepository = ServiceLocator.Current.GetInstance();
var repository = ServiceLocator.Current.GetInstance();
var contentModelUsage = ServiceLocator.Current.GetInstance();
var contactBlockType = contentTypeRepository.Load();
List list = contentModelUsage.ListContentOfContentType(contactBlockType).Select(x => x.ContentLink.ToReferenceWithoutVersion()).ToList();
foreach (ContentReference cr in list)
{
  ContactBlock cb;
  repository.TryGet(cr, out cb);
  if (cb != null)
  {
    if (cb.Email != null && cb.Email.ToLower() == value)
    return false;
  }
}

Maybe switch ToReferenceWithoutVersion for something else?

Any help greatly appreciated.

#141903
Nov 24, 2015 12:42
Vote:
 

Hi,

You can implement the IValidate<T> interface and then filter current content link in the list like this:

public class ContactBlockValidation : ValidationAttribute, IValidate<ContactBlock>
{
    public IEnumerable<ValidationError> Validate(ContactBlock instance)
    {
        var contentTypeRepository = ServiceLocator.Current.GetInstance<IContentTypeRepository>();
        var repository = ServiceLocator.Current.GetInstance<IContentRepository>();
        var contentModelUsage = ServiceLocator.Current.GetInstance<IContentModelUsage>();
        var blockType = contentTypeRepository.Load<ChapterBlock>();
        var currentContent = instance as IContent;

        IEnumerable<ContentUsage> list = contentModelUsage.ListContentOfContentType(blockType);

        if (currentContent != null)
        {
            list = list.Where(x => !x.ContentLink.CompareToIgnoreWorkID(currentContent.ContentLink));
        }

        IEnumerable<ContentReference> references = list.Select(x => x.ContentLink.ToReferenceWithoutVersion()).Distinct();

        foreach (ContentReference cr in references)
        {
            ContactBlock cb;

            if (!repository.TryGet(cr, out cb))
            {
                continue;
            }

            if (cb.Email != null && cb.Email.Equals(instance.Email, StringComparison.OrdinalIgnoreCase))
            {
                return new[]
                {
                    new ValidationError
                    {
                        PropertyName = "Email",
                        ErrorMessage = "A contact block with supplied email already exists."
                    }
                };
            }
        }

        return Enumerable.Empty<ValidationError>();
    }
}
#141926
Nov 24, 2015 15:33
Vote:
 
list = list.Where(x => !x.ContentLink.CompareToIgnoreWorkID(currentContent.ContentLink));

did the trick. Thanks Mattias!

#141940
Nov 24, 2015 19:20
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.