Domanda

I have the following custom required attribute code:

[AttributeUsage(AttributeTargets.Property, AllowMultiple = true, Inherited = true)]
public sealed class AddressRequiredAttribute : RequiredAttribute, IClientValidatable
{
    /// <summary>
    /// The _property name
    /// </summary>
    private string _propertyName;

    /// <summary>
    /// Initializes a new instance of the <see cref="AddressRequiredAttribute"/> class.
    /// </summary>
    /// <param name="propertyName">Name of the property.</param>
    public AddressRequiredAttribute(string propertyName)
        : base()
    {
        _propertyName = propertyName;
    }

    /// <summary>
    /// Checks that the value of the required data field is not empty.
    /// </summary>
    /// <param name="value">The data field value to validate.</param>
    /// <returns>
    /// true if validation is successful; otherwise, false.
    /// </returns>
    protected override ValidationResult IsValid(object value, ValidationContext context)
    {
        if (context.ObjectType.BaseType == typeof(AddressModel))
        {
            PropertyInfo property = context.ObjectType.GetProperty(_propertyName);
            if (property != null && (bool)property.GetValue(context.ObjectInstance))
            {
                return base.IsValid(value, context);
            }
        }

        return ValidationResult.Success;
    }

    /// <summary>
    /// When implemented in a class, returns client validation rules for that class.
    /// </summary>
    /// <param name="metadata">The model metadata.</param>
    /// <param name="context">The controller context.</param>
    /// <returns>
    /// The client validation rules for this validator.
    /// </returns>
    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {
        string errorMessage = this.ErrorMessage;

        // Get the specific error message if set, otherwise the default
        if (string.IsNullOrEmpty(errorMessage) && metadata != null)
        {
            errorMessage = FormatErrorMessage(metadata.GetDisplayName());
        }

        var clientValidationRule = new ModelClientValidationRule()
        {
            ErrorMessage = errorMessage,
            ValidationType = "requiredaddress"
        };

        return new[] { clientValidationRule };
    }

and the following jquery for the client side validation which is run on window.load:

$.validator.addMethod('requiredaddress', function (value, element, params) {
    return value != '';
}, '');

$.validator.unobtrusive.adapters.add('requiredaddress', {}, function (options) {
    options.rules['requiredaddress'] = true;
    options.messages['requiredaddress'] = options.message;
});

However, the clientside doesn't kick in so I get the normal clientside validation working, then the form will submit but come back with the custom errors after postback. All the examples that I have looked at say that my code should be correct so I'm not sure what is wrong here.

Can anyone see anything obvious I'm doing wrong here, thanks

È stato utile?

Soluzione

I did something similar to this and found that if I put the code in the document.ready on window.load it wouldn't work. In the end I went with using the following code placed after the jquery validate scripts:

(function ($) {
    $.validator.addMethod('requiredaddress', function (value, element, params) {
        return value != '';
    }, 'Clientside Should Not Postback');

    // i think you should be able to use this as your adapter
    $.validator.unobtrusive.adapters.addBool('requiredaddress');
})(jQuery);
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top