refresh
refresh

Reputation: 1329

Validation in MVC C#

I following this tutorial for MVC data validation: http://www.tutorialsteacher.com/mvc/implement-validation-in-asp.net-mvc and somehow this is not working. Below is my code:

Model:

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

namespace LayoutProject.Models
{
    public class Book
    {
        [Required]
        public int bookId { get; set; }
        [Required]
        public String title { get; set; }
        [StringLength(50)]
        public String author { get; set; }
        [Range(0,4)]
        public int publicationYear { get; set; }
        public String editor { get; set; }
    }
}

Partial View:

@model LayoutProject.Models.Book

<h4>Books</h4>

@Html.AntiForgeryToken()
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
@Html.HiddenFor(b => b.bookId)

    <table>
        <tr>
            <td>@Html.LabelFor(d=>d.bookId)</td>
            <td>@Html.TextBoxFor(d=>d.bookId)
                @Html.ValidationMessageFor(b => b.bookId, "", new { @class = "text-danger" })
            </td>
        </tr>
        <tr>
            <td>@Html.LabelFor(d=>d.title)</td>
            <td>@Html.TextBoxFor(d=>d.title)</td>
        </tr>
        <tr>
            <td>@Html.LabelFor(d=>d.author)</td>
            <td>@Html.TextBoxFor(d=>d.author)</td>
        </tr>
        <tr>
            <td>@Html.LabelFor(d=>d.publicationYear)</td>
            <td>@Html.TextBoxFor(d=>d.publicationYear)</td>
        </tr>
        <tr>
            <td>@Html.LabelFor(d=>d.editor)</td>
            <td>@Html.TextBoxFor(d=>d.editor)</td>
        </tr>
    </table>

View:

    @{
    ViewBag.Title = "CreateBooks";
}

<h2>CreateBooks</h2>

<form action="/Home/SaveBooks" method="post">
    @Html.Partial("_CreateBook")
    <input id="createBook" type="submit" value="Submit"/>
</form>

As you can see, the bookId is a required field, however when I click on the submit button without entering any bookId, I get no error message. The model would go to the controller and follow any methods written there. Any idea what I might have missed?

Controller:

    [HttpPost]
    public ActionResult SaveBooks(Book book)
    {
        return View(book);
    }

Upvotes: 1

Views: 442

Answers (3)

Pramod
Pramod

Reputation: 96

[Integer]
    [Min(1, ErrorMessage="Please enter Valid bookid.")]
    [Required]
public int bookId { get; set; }

Upvotes: 0

hjardine
hjardine

Reputation: 495

From what I can gather there is two scenarios:

  1. You pre-fill the bookId in the HiddenFor and just use this to hold the ID for the form callback

OR

  1. The user can fill in the bookId using the TextBoxFor which isn't bound as the HiddenFor occurs first

Solution:

If the case is 1. - Remove TextBoxFor, LabelFor and ValidationFor bookID and ensure you are pre-filling the HiddenFor correctly (it is int so will always be valid)

If the case is 2. - Remove the HiddenFor and you should be fine.

UPDATE: As it is of type int, required will always be valid as its default state is 0

If 0 is never valid then you can do something like this:

In your Model:

[PosNumberNoZero(ErrorMessage = "A positive number, bigger than 0 is required")]
public int bookId { get; set; }

//In the same file:

public class PosNumberNoZeroAttribute : ValidationAttribute {
    public override bool IsValid(object value) {
        if (value == null) {
            return true;
        }
        int getal;
        if (int.TryParse(value.ToString(), out getal)) {

            if (getal == 0)
                return false;

            if (getal > 0)
                return true;
        }
        return false;

    }
}

Update 2: This is untested but I think you can use:

[Range(1, int.MaxValue, ErrorMessage = "Please enter a number greater than 0." )]
public int bookId { get; set; }

If 0 is valid then swap 1 for 0

Upvotes: 2

Viktor Bahtev
Viktor Bahtev

Reputation: 4908

It seems that you're missing jquery-validation and jquery.validate.unobtrusive script references. Try to add the following code in your view (or in your layout):

<script src="http://ajax.aspnetcdn.com/ajax/jquery.validate/1.14.0/jquery.validate.js"></script>
<script src="http://ajax.aspnetcdn.com/ajax/mvc/5.2.3/jquery.validate.unobtrusive.js"></script>

Of course you can download them and reference them as a local files.

Also small side note - in C# the properties should be named in PascalCase (the name should starts with a capital letter and every new word starts with a capital letter).

Upvotes: 1

Related Questions