0

I try to use the client side validation on a very simple example and it don't work. I started from an existing example from the internet.

Here it is (see accepted answer): ASP .Net MVC 3 unobtrusive custom client validation

Basically, it uses this blog as solution: http://benjii.me/2010/11/credit-card-validator-attribute-for-asp-net-mvc-3/

So I started from a blank solution and would like to validate that a price is greater than a minimum.

My controller:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View();
    }

    [HttpPost]
    public ActionResult Index(MinPriceViewModel model)
    {
        if (!ModelState.IsValid)
            return View(model);

        return Content("Thank you very much");
    }
}

My view model:

public class MinPriceViewModel
{
    [MinPrice(MinPrice=9.99)]
    [Required]
    public double Price { get; set; }
}

The attribute for validation (client & server):

public class MinPriceAttribute : ValidationAttribute, IClientValidatable
{
    public double MinPrice { get; set; }

    public override bool IsValid(object value)
    {
        if (value == null)
            return true;

        var price = Convert.ToDouble(value);

        if (price < MinPrice)
        {
            return false;
        }

        return true;
    }

    public override string FormatErrorMessage(string name)
    {
        return "Attention le champ " + name + " ne contient pas un prix acceptable.";
    }

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {
        yield return new ModelClientValidationRule
        {
            ErrorMessage = this.ErrorMessage,
            ValidationType = "minprice"
        };
    }
}

The view:

@model MinPriceValidation.Models.MinPriceViewModel

@{
    ViewBag.Title = "Home Page";
}

<script src="../../Scripts/jquery.validate.js" type="text/javascript"></script>
<script src="../../Scripts/jquery.validate.unobtrusive.js" type="text/javascript"></script>

<script type="text/javascript">
    $(function () {
        jQuery.validator.unobtrusive.adapters.addBool('minprice');
    }); 
</script>

@using(Html.BeginForm())
{
    @Html.LabelFor(m => m.Price)
    @Html.TextBoxFor(m => m.Price)
    @Html.ValidationMessageFor(m => m.Price)

    <input type = submit />
}

I placed a breakpoint on my post action in my controller to check whether the client or server validation occurred. When I run the solution and I type 1 and submit, the breakpoint is reached in my controller (post action) >> I concluded that client validation is never used.

I didn't understand because I started from the basic example (credit card validation) and I know this credit card validation works in client validation (I tested it in another solution).

I'm a bit lost.

Any idea why the client validation did not work?

Thanks.


UPDATE

After googling a lot, I see that some people tells we need a javascript function for the client validation like this:

    jQuery.validator.addMethod("minprice", function (value, element, param) {
        // Perform tests here for client validation
        return (value>10);
    });

    jQuery.validator.unobtrusive.adapters.addBool('minprice');

When I test with this added javascript function it works but it seems strange to me that the creait card example doesn't have any javascript function in the view for checking the credit card!!

I'm still lost.

Community
  • 1
  • 1
Bronzato
  • 9,438
  • 29
  • 120
  • 212

2 Answers2

1

Make sure these setting are true in web.config:

   <appSettings>
    <add key="ClientValidationEnabled" value="true"/>
    <add key="UnobtrusiveJavaScriptEnabled" value="true"/>
   </appSettings>

And this script include in page:

<script src="@Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
Min Min
  • 6,188
  • 2
  • 19
  • 17
  • yes, the settings are correct in my web.config and yes, script included but still no luck. Thanks anyway. – Bronzato Mar 24 '12 at 11:15
  • Updated. Could be because of your yield return. – Min Min Mar 24 '12 at 11:45
  • Yes, you are right. We are limited to adding support to the MVC client-side validation for the underlying jQuery validation rules. In this case, there was another option "Remote Validation". Something like http://deanhume.com/Home/BlogPost/mvc-3-and-remote-validation/51 – Min Min Mar 24 '12 at 12:38
  • Thanks. Remote Validation is an interesting option but not for my cas. I know something more 'classic' should suit me for client side validation. – Bronzato Mar 24 '12 at 12:47
1

When you say that you are seeing people using this with credit card and it works without the need of a custom javascript function I suppose you are reffering to the following post.

A credit card validation rule is directly built in the jquery validate plugin. That's why you don't need to write a custom validation function.

As far as a minprice rule is concerned, there's no such thing, so you need to write a custom javascript function to define what minprice means.

This being said I get the feeling that you are reinventing some wheel with this attribute as you could simply do:

[Range(9.99, double.MaxValue)]
[Required]
public double Price { get; set; }

and since we are talking about prices, it is recommended to use a decimal type on your model:

[Range(9.99, double.MaxValue)]
[Required]
public decimal Price { get; set; }

Now you will get automatic client side and server side validation.

Community
  • 1
  • 1
Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • That works but then when the min price changes, you need a programmer to change the code. This is a marketing rule and should be dynamic and changed by non-programmers without a rebuild/redeployment of the application. – RickAndMSFT Mar 25 '12 at 16:52