8

I'm trying to implement a custom validation attribute with client-side validation too.

My attribute looks like:

public class FileSize : ValidationAttribute, IClientValidatable
{
    private readonly int _size;

    public FileSize(int size)
    {
        ErrorMessage = "Invalid size.";
        _size = size;
    }

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {
        var rule = new ModelClientValidationRule
        {
            ValidationType = "fileSize",
            ErrorMessage = ErrorMessage
        };

        rule.ValidationParameters["size"] = _size;

        yield return rule;
    }

    public override bool IsValid(object value)
    {
        return ((HttpPostedFileBase) value).ContentLength < _size;
    }
}

and the script includes in my view looks like:

<script src="@Url.Content("~/Scripts/jquery-1.4.4.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.js")" type="text/javascript"></script>
<script type="text/javascript">
    $(function () {
        $.validator.unobtrusive.adapters.addSingleVal('fileSize', 'size');
    });
</script>

The problem is that even with all of those script includes and the function that registers a new adapter, then the client-side validation is still not working, it simply just keep using the server-side validation only...

Any ideas?

2
  • 2
    Did you find out a solution to this? If yes, can you please share it? Commented Feb 28, 2013 at 5:10
  • Bump: I am actually looking for the exact same type of validator (filesize). Did you ever find a solution?? Commented Sep 30, 2015 at 16:09

1 Answer 1

9

You are missing some JavaScript.

Look at Brad Wilsons "greater" example from his Advanced ASP.NET MVC 3 talk.

Some sourcecode from it:

(function ($) {
$.validator.addMethod("jqgreater", function (value, element, params) {
    var thisValue, otherValue;
    if (this.optional(element)) { // No value is always valid
        return true;
    }

    thisValue = parseInt(value);
    otherValue = parseInt($(params).val());
    return thisValue > otherValue;
});

function getModelPrefix(fieldName) {
    return fieldName.substr(0, fieldName.lastIndexOf(".") + 1);
}

function appendModelPrefix(value, prefix) {
    if (value.indexOf("*.") === 0) {
        value = value.replace("*.", prefix);
    }
    return value;
}

$.validator.unobtrusive.adapters.add("greater", ["other"], function (options) {
    var prefix = getModelPrefix(options.element.name),
        other = options.params.other,
        fullOtherName = appendModelPrefix(other, prefix),
        element = $(options.form).find(":input[name=" + fullOtherName + "]")[0];

    options.rules["jqgreater"] = element;  // element becomes "params" in callback
    if (options.message) {
        options.messages["jqgreater"] = options.message;
    }
});
} (jQuery));
Sign up to request clarification or add additional context in comments.

1 Comment

Thats only if you want to make custom adapter... All I want is to use the existing one "addSingleVal" (bradwilson.typepad.com/blog/2010/10/…)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.