Troubleshooting ASP.NET MVC3: The mystery behind why my custom validation attributes always seem to fail

After completing several tutorials, I have successfully implemented my models from a library file (dll). Everything seems to be functioning correctly except for one issue.

Here is 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; }
}

Although the attributes are recognized and highlighted accordingly, when submitting the form it accepts any input.

I have included the code below for validation attributes, understanding that this validation occurs on the server side upon form submission.

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

Firstly, here is the Price validation attribute (ensuring no negative values).

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

    }

Next, we have the 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);
        }

}

Answer №1

Validation of the page will not occur automatically. To validate the page, you must include the following code in your controller:

// Assuming your view is named Temp...
public class TempController : Controller
{
    // This method will generate the view with the RoomBookingInsert model
    // NOTE: it does not have an HttpPost attribute
    public ActionResult Temp()
    {
         return View(new MyLibrary.RoomBookingInsert());
    }

    // This is the postback 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);
        }

        // Additional logic can be implemented here
        ...
    }

}

Answer №2

I noticed that you forgot to include the reference to jQuery for client validation. Please make sure to double check this.

When it comes to server validation, be sure to explicitly Validate as mentioned in user1039947's answer.

A great tool to consider is 'Mvc.Futures', which offers a variety of validators implemented, as discussed here

Answer №3

There is a significant issue I noticed within your datetime validator - it currently returns true when the value is null or not a datetime, when in fact it should be returning false.

Additionally, there seems to be an error in the decimal validator as well. It does not account for null values and fails to verify if the input is a valid decimal. Instead, it simply encases the value, causing exceptions if it is not a decimal.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Best practices for managing jqGrid AJAX requests

Looking to create a more flexible solution in jqGrid by setting up a custom function for AJAX calls instead of hard-coding the URL in the definition. I've experimented with a few approaches, but haven't found one that perfectly mirrors the direc ...

Tips on initiating a $http.get request every second using a service

I am working on an angular application that includes a $http.get request. While it currently functions properly, I need it to be executed every second in order to retrieve new data. Service: angular.module('adf.widget.liveCharts') .service(&a ...

How can the HTML source code be printed without showing it in a window or tab?

Here's the scenario: I'm making an ajax post request to a controller action, which returns complete html source code. I want to print this html source as if it were being displayed in a browser without opening a new tab or window. Is there a way ...

Tips on creating and elegantly showcasing an image from a PDF document on the screen with React-PDF

I am currently working on developing a user interface in JavaScript (React) to enable users to create PDFs directly on the screen. The concept involves having input boxes on one side, which instantly update the fields on the PDF displayed on the other side ...

AngularJS version 1.5.11 experiencing issues with ng-repeat functionality

Having an application built on angularJS v1.5.11, I encountered a major issue while attempting to use ng-repeat in a table format like below: <tbody> <tr ng-repeat="score in data.result"> <td ng-repeat="item in score"> {{ item }} & ...

Troubleshooting issue: Django and Javascript - Why is my dependent dropdown feature not

I am new to using a combination of Javascript and Django. Below is the script I have written: <script> $(document).ready(function() { $("#source").change(function() { var el = $(this); var reg = ...

Returning to the location in the file where the redirect function was invoked in the Express framework

In my current project, I am working on an Express app and facing a challenge. I need to redirect after collecting data in a function, complete the redirect, return the data, and then resume from where I left off. For instance: > res.redirect('my/ ...

Set a variable to represent a color for the background styling in CSS

My goal is to create an application that allows users to change the background color of a button and then copy the CSS code with the new background color from the <style> tags. To achieve this, I am utilizing a color picker tool from . I believe I ...

What is the equivalent of defining conditional string types in Typescript similar to flow?

type UpsertMode = | 'add' | 'update' | 'delete'; interface IUpsertMembers { mode: UpsertMode; } const MagicButton = ({ mode: UpsertMode }) => { return ( <button>{UpsertMode}</button> ); } const Upse ...

Featherlight is experiencing issues with running Ajax requests

I'm currently working on integrating an ajax photo uploading script into a Featherlight lightbox, but I'm running into issues! If anyone could help me figure out what's going wrong, that would be greatly appreciated. I've already includ ...

delay of Paypal API disbursement for transactions with a range of money values

After browsing through various resources such as this link, that link, and another one on the PayPal developer website, I attempted to implement a payment processing system that allows users to approve a preset amount of money. Similar to services like Ube ...

Arranging objects in an array based on a separate array of strings

Here is an array of objects that I need to rearrange: var items = [ { key: 'address', value: '1234 Boxwood Lane' }, { key: 'nameAndTitle', value: 'Jane Doe, Manager' }, { key: 'contactEmail', value: ...

Objects array - does not support the 'push' function

In my code snippet, it looks like this: var result = {}; for (var i = 0; i < questions.length; i++) { if(result.hasOwnProperty(questions[i].group)) { var questionsInGroup = result[questions[i].group]; log.debug(typeof questionsInGroup); ...

Is it possible to utilize href alongside the urlRouterProvider?

Within my angularjs application, I opted to switch from using ngRoute (routeProvider) to ui.router (urlRouterProvider) module and stateProvider for transitioning between different states in the app. However, I recently discovered that ui-router only suppo ...

How to access variables with dynamic names in Vue.js

I'm curious if it's possible to dynamically access variables from Vue’s data collection by specifying the variable name through another variable. For instance, consider the following example: Here are some of the variables/properties: var sit ...

Utilizing JavaScript to bring JSON image data to the forefront on the front-end

In my quest to utilize JavaScript and read values from a JSON file, I aim to showcase the image keys on the front-end. To provide clarity, here's an excerpt from the JSON dataset: { "products": {"asin": "B000FJZQQY", "related": {"also_bought": ...

Exploring the realm of styling with React JS

Currently, I am facing an issue while working with material-ui for my web design. Here is the code snippet that I am using: const useStyles = makeStyles((theme) => ({ card: { marginTop: theme.spacing(10), direction:"column", alig ...

Interactive drop-down menus created on the fly

I am currently working on dynamically generating inputs using Angular and Angular Material. Each time the user clicks on the Add button, a new dropdown should be created. However, I am encountering an error message that says: 'Error: [$parse:syntax ...

Navigating through and extracting data from an object in JavaScript

Given the function call destroyer([1, 2, 3, 1, 2, 3], 2, 3);, I am trying to retrieve the last 2, 3 part after the initial array. However, I am unsure about how to achieve this. When I use return arr[6]; or return arr[1][0], both statements do not return ...

What is the best way to leverage command line arguments with AngularJS Protractor?

Currently, I am utilizing Protractor for executing extensive end-to-end tests. Instead of storing login credentials in a spec file, I am keen on passing them through the command line. Upon stumbling across a post showcasing the usage of process.argv.forEac ...