While farm administrators can always go and block a rogue solution from the Manage User Solutions screen, there is another proactive way in which solutions can be checked for validations at the time of activation, and any solutions failing validation can be prevented from activation. This can be achieved by developing a sandboxed solution validator.
The following steps are used to develop a solution validator:
1. Create a class inheriting from Microsoft.SharePoint.UserCode.SPSolutionValidator
class.
2. Provide a System.Runtime.InteropServices.Guid
for the validator that will be used as ProviderID
for the validator.
3. Define a default constructor in the validator that takes no arguments.
4. Define another constructor that takes a Microsoft.SharePoint.UserCode.SPUserCodeService
object.
5. Set the Signature
property to a unique value in the second constructor.
6. Override the ValidateSolution
and ValidateAssembly
methods. ValidateSolution
is called once for each solution, and ValidateAssembly
is called once for each assembly in the solution.
7. Specify an error page to display when a solution fails validation.
8. Register the solution validator with the Sandboxed Code Service.
The following code demonstrates the preceding steps, where we are trying to block any solution having a solution name beginning with the letters FailValidation
.
[Guid("45861A3A-71FB-438C-9B60-DA57DE2F94ED")]
class CustomSolutionValidator : SPSolutionValidator
{
private const string validatorName = "Custom Solution Validator";
public CustomSolutionValidator() { }
public CustomSolutionValidator(SPUserCodeService userCodeService)
: base(validatorName, userCodeService)
{
this.Signature = 2222;
}
public override void
ValidateSolution(
SPSolutionValidationProperties properties)
{
base.ValidateSolution(properties);
//Check the name of the package
if (properties.PackageFile.Location.StartsWith("FailValidation",
StringComparison.CurrentCultureIgnoreCase))
{
properties.ValidationErrorMessage =
"Sorry, your solution failed Validation.";
properties.ValidationErrorUrl =
"/_layouts/CustomSolutionValidator/CustomValidationError.aspx";
properties.Valid = false;
}
else
{
properties.Valid = true;
}
}
public override void ValidateAssembly(
SPSolutionValidationProperties properties, SPSolutionFile assembly)
{
base.ValidateAssembly(properties, assembly);
properties.Valid = true;
}
Create a new project that can be deployed at farm level. Create the CustomSolutionValidator
class as per the steps discussed previously. Add a new farm level feature to the solution. To register the validator with the sandboxed user code service, add a feature activated event receiver as demonstrated in the following code:
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
SPUserCodeService userCodeService = SPUserCodeService.Local;
CustomSolutionValidator validator =
new CustomSolutionValidator(userCodeService);
userCodeService.SolutionValidators.Add(validator);
}
Next add a new application page to the solution to be deployed under the layouts folder under the SharePoint root. This application page displays as an error page when a solution fails validation. Build and deploy the solution. Make sure that your farm level custom solution validator feature is active, using Central Administration, as demonstrated in Figure 21.16.
Now test the validator by uploading a solution with a solution name beginning with FailValidation. Upload the solution and click the Activate button, as demonstrated in Figure 21.17.
If all goes well, the solution fails validation and is not activated. Instead you are taken to the custom error page as shown in Figure 21.18.
Thus you can see that solution validators offer a proactive way of blocking rogue solutions from activation.