1

Could someone write me an example of a Validation Attribute that validates a Dependent field that could be Boolean, String or a HttpPostedFile value. I've been looking but the examples that I've tried don't work for all those situations. e.g or if you could figure out why my page doesn't submit after validation - this is the link to an example link here

E.g. 1 if UseReferenceId is false then use department image

public bool UserReferenceId { get; set; }

[RequiredIf("UseReferenceId", false, ErrorMessage="Error please select a Advert image")]
public HttpPostedFileBase DepartmentImageFile { get; set; }

E.g 2

[RequiredIf("AdvertLink", "*", ErrorMessage="Please enter a url for the Image")]
public HttpPostedFileBase AdvertImageFile { get; set; }

[RequiredIf("AdvertImageFile", "*", ErrorMessage="Error please select a Advert image")]
public HttpPostedFileBase AdvertLink { get; set; }

i've been using this code but my page just won't submit after validation is complete.

data-val-requiredif="Url is required for advertisement url." 
data-val-requiredif-dependentproperty="UseReferenceId" data-val-requiredif-targetvalue="false"

public class RequiredIfAttribute : ValidationAttribute, IClientValidatable
{
    protected RequiredAttribute _innerAttribute;

    public string DependentProperty { get; set; }
    public object TargetValue { get; set; }

    public bool AllowEmptyStrings
    {
        get
        {
            return _innerAttribute.AllowEmptyStrings;
        }
        set
        {
            _innerAttribute.AllowEmptyStrings = value;
        }
    }

    public RequiredIfAttribute(string dependentProperty, object targetValue)
    {
        _innerAttribute = new RequiredAttribute();
        DependentProperty = dependentProperty;
        TargetValue = targetValue;
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        // get a reference to the property this validation depends upon
        var containerType = validationContext.ObjectInstance.GetType();
        var field = containerType.GetProperty(DependentProperty);

        if (field != null)
        {
            // get the value of the dependent property
            var dependentValue = field.GetValue(validationContext.ObjectInstance, null);
            // trim spaces of dependent value
            if (dependentValue != null && dependentValue is string)
            {
                dependentValue = (dependentValue as string).Trim();

                if (!AllowEmptyStrings && (dependentValue as string).Length == 0)
                {
                    dependentValue = null;
                }
            }

            // compare the value against the target value
            if ((dependentValue == null && TargetValue == null) ||
                (dependentValue != null && (TargetValue.Equals("*") || dependentValue.Equals(TargetValue))))
            {
                // match => means we should try validating this field
                if (!_innerAttribute.IsValid(value))
                    // validation failed - return an error
                    return new ValidationResult(FormatErrorMessage(validationContext.DisplayName), new[] { validationContext.MemberName });
            }
        }

        return ValidationResult.Success;
    }

    public virtual IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {
        var rule = new ModelClientValidationRule
        {
            ErrorMessage = FormatErrorMessage(metadata.GetDisplayName()),
            ValidationType = "requiredif",
        };

        string depProp = BuildDependentPropertyId(metadata, context as ViewContext);

        // find the value on the control we depend on;
        // if it's a bool, format it javascript style 
        // (the default is True or False!)
        string targetValue = (TargetValue ?? "").ToString();
        if (TargetValue is bool)
            targetValue = targetValue.ToLower();

        rule.ValidationParameters.Add("dependentproperty", depProp);
        rule.ValidationParameters.Add("targetvalue", targetValue);

        yield return rule;
    }

    private string BuildDependentPropertyId(ModelMetadata metadata, ViewContext viewContext)
    {
        // build the ID of the property
        string depProp = viewContext.ViewData.TemplateInfo.GetFullHtmlFieldId(DependentProperty);
        // unfortunately this will have the name of the current field appended to the beginning,
        // because the TemplateInfo's context has had this fieldname appended to it. Instead, we
        // want to get the context as though it was one level higher (i.e. outside the current property,
        // which is the containing object, and hence the same level as the dependent property.
        var thisField = metadata.PropertyName + "_";
        if (depProp.StartsWith(thisField))
            // strip it off again
            depProp = depProp.Substring(thisField.Length);
        return depProp;
    }
}
4

0 回答 0