Skip to content

Instantly share code, notes, and snippets.

@PNergard
Last active February 19, 2019 15:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save PNergard/41d38a7daeb0c92845454d55c630f6f3 to your computer and use it in GitHub Desktop.
Save PNergard/41d38a7daeb0c92845454d55c630f6f3 to your computer and use it in GitHub Desktop.
An attribute and a IValidate class that gives the developer the options to point out an IList<ContentReference> property from a string property decorated with a SelectMany attribute so when the editor changes the selectmany property the string contentreferences are added to the IList property so we get an automatically check that a SelectMany un…
using EPiServer.Core;
using EPiServer.DataAbstraction;
using EPiServer.ServiceLocation;
using EPiServer.Validation;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Web;
namespace Alloy.Business.Validators
{
public class SelectManyContentReferenceValidator : IValidate<ContentData>
{
List<ValidationError> errorMessages = new List<ValidationError>();
/// <summary>
/// Get a list of all properties on type that are decorated with SelectManyListProperty attribute
/// </summary>
/// <param name="ContentInstance"></param>
/// <returns>Dictionary with decorated property name, property name of Ilist property to be populated with contentreferences</returns>
private static Dictionary<string, string> GetSelectManyProperties(ContentData ContentInstance)
{
Dictionary<string, string> _dict = new Dictionary<string, string>();
var repo = ServiceLocator.Current.GetInstance<IContentTypeRepository>();
var type = repo.Load(((IContent)ContentInstance).ContentTypeID);
PropertyInfo[] props = type.ModelType.GetProperties();
foreach (PropertyInfo prop in props)
{
object[] attrs = prop.GetCustomAttributes(true);
foreach (object attr in attrs)
{
SelectManyListProperty listProperty = attr as SelectManyListProperty;
if (listProperty != null)
{
string propName = prop.Name;
string listPropName = listProperty.Name;
_dict.Add(propName, listPropName);
}
}
}
return _dict;
}
/// <summary>
/// Validates all properties on type and checks to see if they are decorated with SelectManyListProperty attribute. If yes all string references are converted to ContentReferences and added to specified
/// IList<ContentReference> property
/// </summary>
/// <param name="instance"></param>
/// <returns>Empty list of errormessages</returns>
public IEnumerable<ValidationError> Validate(ContentData instance)
{
//Get all SelectMany properties that should be validated
var dictPropertiesToValidate = GetSelectManyProperties(instance);
foreach (PropertyData propertyData in instance.Property)
{
if (dictPropertiesToValidate.ContainsKey(propertyData.Name))
{
var sourcePropertyName = propertyData.Name;
var targetPropertyName = dictPropertiesToValidate[propertyData.Name];
instance.Property[targetPropertyName].Clear();
if (string.IsNullOrEmpty(instance.GetPropertyValue(propertyData.Name))) continue;
var contentRefs = propertyData.Value.ToString().Split(",".ToCharArray()).ToList().Select(x => new ContentReference(x)).ToList();
instance.SetValue(targetPropertyName, contentRefs);
}
}
return errorMessages;
}
} //class
} //namepace
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace Alloy.Business.Validators
{
public class SelectManyListProperty : Attribute
{
public string Name { get; set; }
public SelectManyListProperty(string name)
{
this.Name = name;
}
}
}
@PNergard
Copy link
Author

Implement the Attribute and Validator in your solution. Example code below.

SelectMany(typeof(factoryclass))
SelectManyListProperty("ListPropertyName")
public virtual string SelectManyProp { get; set; }

public virtual IList ListPropertyName {get; set;}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment