Search code examples
validationparameterspostsharp

PostSharp Parameter Validation - Optional String with Maximum Length


I am using PostSharp 3.1 for parameter validation on a web service.

I have an optional string parameter which must be less than 50 characters when passed.

I currently have [StringLength(50)] which means that a string must be passed, string.Empty can be passed but null cannot.

null is valid for this parameter.

The way that I need it to work is the same as the [EmailAddress] validation - if null is passed, do not validate, else validate if any string is passed.

Can this be done?


Solution

  • I have written a custom validation attribute as follows:

    using System;
    
    using PostSharp.Aspects;
    using PostSharp.Patterns.Contracts;
    using PostSharp.Reflection;
    
    public class NullOrStringLengthAttribute : LocationContractAttribute, ILocationValidationAspect<string>
    {
        private readonly int maximum;
    
        public NullOrStringLengthAttribute(int maximum)
        {
            this.maximum = maximum;
    
            this.ErrorMessage = "The parameter '{0}' must be a string with a maximum length of " + maximum + ".";
        }
    
        public Exception ValidateValue(string value, string locationName, LocationKind locationKind)
        {
            if (value == null)
            {
                return null;
            }
    
            return value.Length > this.maximum ? this.CreateArgumentException(value, locationName, locationKind) : null;
        }
    
    }
    

    EDIT: Updated to include minimum string length and new PostSharp 4.x error message patterns:

    using System;
    
    using PostSharp.Aspects;
    using PostSharp.Patterns.Contracts;
    using PostSharp.Reflection;
    
    public class NullOrStringLengthAttribute : LocationContractAttribute, ILocationValidationAspect<string>
    {
        public NullOrStringLengthAttribute(int maximumLength)
        {
            this.ErrorMessage = string.Format("The {{2}} must be null or a string with a maximum length of {0}.", maximumLength);
            this.MaximumLength = maximumLength;
            this.MinimumLength = 0;
        }
    
        public NullOrStringLengthAttribute(int minimumLength, int maximumLength)
        {
            if (maximumLength != int.MaxValue)
            {
                this.ErrorMessage = string.Format("The {{2}} must be null or a string with length between {0} and {1}.", minimumLength, maximumLength);
            }
            else
            {
                this.ErrorMessage = string.Format("The {{2}} must be null or a string with a minimum length of {0}.", minimumLength);
            }
    
            this.MaximumLength = maximumLength;
            this.MinimumLength = minimumLength;
        }
    
        public int MaximumLength { get; private set; }
    
        public int MinimumLength { get; private set; }
    
        public Exception ValidateValue(string value, string locationName, LocationKind locationKind)
        {
            if (value == null)
            {
                return null;
            }
    
            if (value.Length < this.MinimumLength || value.Length > this.MaximumLength)
            {
                return this.CreateArgumentException(value, locationName, locationKind);
            }
    
            return null;
        }
    }