Writing custom attributes
Write custom attributes to improve the editor experience, add business rules, or add custom validation.
Restricting access for editing a certain property
You can restrict access in the following ways:
- Create a ValidationAttribute to add server-side validation when data is saved.
- Implement IMetadataAware for your attribute to add metadata that affects the editing experience of the property.
You can combine the implementation of the IMetadataAware attribute with a ValidationAttribute to control which roles can edit a specific property.
The following example shows how to make a property read-only in the editorial interface through an attribute:
using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;
namespace EPiServer.Samples
{
public class PropertyEditRestrictionAttribute : ValidationAttribute, IMetadataAware
{
public PropertyEditRestrictionAttribute(string[] allowedRoles)
{
AllowedRoles = allowedRoles;
}
public string[] AllowedRoles { get; set;
}
public void OnMetadataCreated(ModelMetadata metadata)
{
foreach (string role in AllowedRoles)
{
if (EPiServer.Security.PrincipalInfo.CurrentPrincipal.IsInRole(role))
{
return;
}
}
metadata.IsReadOnly = true;
}
}
}
Usage on the model should look as follows. The example uses the group name administrators2 to make sure you are not member of this group.
[PropertyEditRestriction(new string[]{"administrators2"})]
public virtual XhtmlString MainBody { get; set; }
Go to the EPiServer editorial interface to see that the editor was disabled in the all properties view:
![](/contentassets/2c710f11ab74490695e96c337da7812c/readonly_thumb.png)
In the on-page edit view, the property looks editable, but if you cannot edit the property and you click on the overlay, edit view loads a read-only editor and removes the overlay entirely.
![](/contentassets/2c710f11ab74490695e96c337da7812c/readonlyonpageedit_thumb.png)
Validation on the server
The following example adds server validation to the same attribute from the example in the previous section, so that you cannot post a fake property update to the server even without having the correct access.
using System;
using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;
using EPiServer.Core;
namespace EPiServer.Samples
{
public class PropertyEditRestrictionAttribute : ValidationAttribute, IMetadataAware
{
public PropertyEditRestrictionAttribute(string[] allowedRoles)
{
AllowedRoles = allowedRoles;
}
public string[] AllowedRoles { get; set; }
public void OnMetadataCreated(ModelMetadata metadata)
{
foreach (string role in AllowedRoles)
{
if (EPiServer.Security.PrincipalInfo.CurrentPrincipal.IsInRole(role))
{
return;
}
}
//Comment row below to test the server validation.
metadata.IsReadOnly = true;
}
public override string FormatErrorMessage(string name)
{
return "You do not have access to change " + name;
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var contentData = validationContext.ObjectInstance as IContentData;
if (contentData == null)
{
//This attribute only handles instances of IContentData. return ValidationResult.Success;
}
if (!contentData.Property[validationContext.MemberName].IsModified)
{
return ValidationResult.Success;
}
if (Validate())
{
return ValidationResult.Success;
}
else { return new ValidationResult("You do not have access"); }
}
public override bool RequiresValidationContext
{
get
{
return true;
}
}
public bool Validate()
{
foreach (string role in AllowedRoles)
{
if (EPiServer.Security.PrincipalInfo.CurrentPrincipal.IsInRole(role))
{
return true;
}
}
return false;
}
}
}
You can comment out the line that makes the property read-only, and edit the property to validate that the server validation actually does work.
![](/contentassets/2c710f11ab74490695e96c337da7812c/servervalidation_thumb.png)
Do you find this information helpful? Please log in to provide feedback.
Last updated: Feb 23, 2015