0

Basically, I have correctly followed different tutorials. Now, my models are taken from a library file (dll) which shouldnt be a problem as everything else functions fine.

My model:

public class RoomBookingInsert
{

    public Int32 CostCentreNo { get; set; }
    public Int32 CustomerAccNo { get; set; }
    public Int32 RoomNo { get; set; }
    public Int32 ServiceCode { get; set; }
    [PriceValidation]
    public Decimal HourlyRate { get; set; }
    [DataType(DataType.Date)]
    [DateRange("2010/12/01", "2010/12/16")]
    public DateTime StartDate { get; set; }
}

The attributes ARE recognised, as they go blue accordingly, and autocomplete detects them. However, when I post my form, it accepts anything.

I have included my code below for validation attributes, and I recognise that this is server side, and so happens on the post command.

My Form in asp.net mvc3 using razor:

@model MyLibrary.RoomBookingInsert

@{
    ViewBag.Title = "Temp";
}

<h2>Temp</h2>

<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>

@using (Html.BeginForm()) {
    @Html.ValidationSummary(true)
    <fieldset>
        <legend>RoomBookingInsert</legend>

        @Html.EditorForModel()
        <p>
            <input type="submit" value="Save" />
        </p>
    </fieldset>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>

Here is my first Price validation (ensuring that it never goes negative).

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;

    public class PriceValidationAttribute : ValidationAttribute

    {
        private decimal minPrice = 0.00M;
        private decimal maxPrice = 100.00M;

            public PriceValidationAttribute()
            {
            }
            public override bool IsValid(object value)
            {
                decimal price = (decimal)value;
                if (price < this.minPrice || price > this.maxPrice)
                    return false;
                return true;
            }

    }

Here is my Date Range validation:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel.DataAnnotations;
using System.Globalization;

    public class DateRangeAttribute : ValidationAttribute
    {
        private const string DateFormat = "yyyy/MM/dd";
        private const string DefaultErrorMessage =
               "'{0}' must be a date between {1:d} and {2:d}.";

        public DateTime MinDate { get; set; }
        public DateTime MaxDate { get; set; }

        public DateRangeAttribute(string minDate, string maxDate)
            : base(DefaultErrorMessage)
        {
            MinDate = ParseDate(minDate);
            MaxDate = ParseDate(maxDate);
        }

        public override bool IsValid(object value)
        {
            if (value == null || !(value is DateTime))
            {
                return true;
            }
            DateTime dateValue = (DateTime)value;
            return MinDate <= dateValue && dateValue <= MaxDate;
        }
        public override string FormatErrorMessage(string name)
        {
            return String.Format(CultureInfo.CurrentCulture,
                ErrorMessageString,
                name, MinDate, MaxDate);
        }

        private static DateTime ParseDate(string dateValue)
        {
            return DateTime.ParseExact(dateValue, DateFormat,
                 CultureInfo.InvariantCulture);
        }

}
2
  • 2
    What does the method in the controller look like? I assume you are checking ModelState.IsValid? Commented Dec 9, 2011 at 10:58
  • I dont suppose you can post this as an answer with some info/example. I think this is where I am going wrong Commented Dec 9, 2011 at 11:17

3 Answers 3

1

The page will not be automatically validated. In order to validate the page what you need to do on your controller is something like this:

// Guessing your view is called Temp...
public class TempController : Controller
{
    // This method will create the view with the RoomBookingInsert model
    // NOTE: it has no HttpPost attribute
    public ActionResult Temp()
    {
         return View(new MyLibrary.RoomBookingInsert());
    }

    // This is the post back action method for your view
    // NOTE: this has an HttpPost attribute
    [HttpPost]
    public ActionResult Temp(MyLibrary.RoomBookingInsert model)
    {
        // Always start by checking the model state and if it is not valid
        // return the view with the original model
        if(!ModelState.IsValid)
        {
            return View(model);
        }

        // Rest of logic goes here
        ...
    }

}
Sign up to request clarification or add additional context in comments.

5 Comments

Slightly confused. Is this the method where the post goes to. i.e. my create method. or the method which displays it, i.e. my insert method. (sorry for calling my view temp)
Oh. I just realised that I shouldnt have a create method. From your code, clicking action will run this code, and if fails, go back to insert, else create the booking.
This is the post back function (so what is called when the form is submitted). Normally you'd have a matching ActionResult Temp() method - I will update the example...
Excellent stuff. Got my custom validations working now. Cheers. Time to play around with it, and give my website the fully working effect.
It had previously baffled me for weeks, so big thanks! :) :). Thanks for update too, works a charm.
1

For client validation, I do not see, you have included the reference to jQuery itself. Can you please double check?

For server validation, you should Validate it explicitly (like described in user1039947's answer.

I would suggest you to use 'Mvc.Futures', which has some of the validators implemented

3 Comments

In addition, i do not see, that IClientValidatable( msdn.microsoft.com/en-us/library/… ) is implemented
This is required to enable client validation for custom validators
I would suggest you to use Mvc.Futures, which has some of the validators implemented: weblogs.asp.net/imranbaloch/archive/2011/02/05/…
0

One big problem I spotted in your datetime validator is that you return true when value is null or it's not a datetime. It should return false.

Another problem in the decimal validator, you don't check value for null, neither you check if it's a valid decimal. You just box it, and if the value isn't a decimal, it will throw an exception.

1 Comment

It is pretty normal in a validator to return true if you get null input since you would defer that validation to the Required validator. It's a single responsibility principal thing: a validator validates one thing only, not for example whether it exists and it is in a given range.

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.