MVC Data Annotations in Razor

2019-07-23 16:58发布

问题:

I'm trying to use Data Annotations in my MVC project (Mono/.NET 4.5). I've created my model and added all the appropriate annotations. I have my view and controller appropriately wired up. However, the validation just doesn't seem to be happening. I've tried everything I can find to no avail. As this is my first time working with Razor and Data Annotations, I imagine there is some setup piece I'm missing but I can't find it for the life of me. Here's my code:

Model

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

namespace MyWebsite
{
  public class RegisterViewModel : BaseViewModel
  {
    #region properties
    [Required(ErrorMessage = "Required")]
    [StringLength(50)]
    [DisplayName("First Name")]
    public string FirstName { get; set; }
    [Required(ErrorMessage = "Required")]
    [StringLength(100)]
    [DisplayName("Last Name")]
    public string LastName { get; set; }
    [StringLength(50)]
    [DisplayName("Display Name")]
    public string DisplayName { get; set; }
    [Required(ErrorMessage = "Required")]
    [StringLength(255)]
    [DisplayName("Email Address")]
    public string EmailAddress { get; set; }
    #endregion

    #region ctor
    public RegisterViewModel ()
    {

    }
    #endregion

  }
}

Controller

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace MyWebsite.Controllers
{
  public class AccountController : Controller
  {
    public ActionResult Register()
    {
        ViewData ["IsComplete"] = false;
        ViewData ["RequiredVouches"] = WebSettings.RequiredVouches;

        return View ();
    }

    [HttpPost]
    public ActionResult Register(FormCollection formData)
    {
        if (ModelState.IsValid) {
            //TODO: Put the data
            ViewData ["IsComplete"] = true;
        }
        return View ();
    }
  }
}

View

@model SummerIsles.Web.RegisterViewModel
@section Styles {
<link href="~/Content/themes/base/Account.css" rel="stylesheet" type="text/css" />
}
@{
if((bool)@ViewData["IsComplete"]) {
    <h1>Registration Request Complete!</h1>
    <div class="page-message">
        <p>
           Confirmation message goes here
        </p>
    </div>
}
else {
    <h1>Registration</h1>
    <div class="page-message">
        <p>
            Instruction text goes here
        </p>
    </div>
    using (Html.BeginForm()) {
        @Html.ValidationSummary(false)
        <fieldset>
            <legend>Your Information</legend>

            <div class="group column-1">
                @Html.LabelFor(modelItem => @Model.FirstName)
                @Html.EditorFor(modelItem => @Model.FirstName, new { htmlAttributes = new { @class="form-control" } } )
                @Html.ValidationMessageFor(modelItem => @Model.FirstName)

                @Html.LabelFor(modelItem => @Model.DisplayName)
                @Html.EditorFor(modelItem => @Model.DisplayName, new { htmlAttributes = new { @class="form-control" } } )
                @Html.ValidationMessageFor(modelItem => @Model.DisplayName)
            </div>

            <div class="group column-2">
                @Html.LabelFor(modelItem => @Model.LastName)
                @Html.EditorFor(modelItem => @Model.LastName, new { htmlAttributes = new { @class="form-control" } } )
                @Html.ValidationMessageFor(modelItem => @Model.LastName)

                @Html.LabelFor(modelItem => @Model.EmailAddress)
                @Html.EditorFor(modelItem => @Model.EmailAddress, new { htmlAttributes = new { @class="form-control" } } )
                @Html.ValidationMessageFor(modelItem => @Model.EmailAddress)
            </div>

            <div class="button-options">
                <button id="btnSubmit" type="submit" formmethod="post" class="btn btn-danger">Submit</button>
                <a id="btnCancel" href="~/" class="btn">Cancel</a>
            </div>
        </fieldset>
    }
  }
}

Also, I have added the jquery validation scripts to my layout file and have also enabled client validation in the web.confg.

Layout Header

<head>
  <!--some other css and such-->
  <script src="~/Scripts/jquery.validate.min.js"></script>
  <script src="~/Scripts/jquery.validate.unobstrusive.min.js"></script>
</head>

Web.config

<appSettings>
   <!--some other stuff-->
   <add key="ClientValidationEnabled" value="true" />
   <add key="UnobtrusiveJavaScriptEnabled" value="true" />
</appSettings>

Basically, when I click submit, it thinks the model is perfectly valid (ModelState.IsValid returns true in the controller) and the validation stuff (which I would expect to fire before the post back to the controller) never seems to fire. I get no validation messages even with a completely blank form (despite having the "Required" data annotation). What am I missing?

回答1:

@Html.ValidationMessageFor(modelItem => @Model.LastName)

should be

@Html.ValidationMessageFor(modelItem => modelItem.LastName)

for all your HtmlHelpers, including TextBoxFor and LabelFor etc.

Also

public ActionResult Register(FormCollection formData)

should be

public ActionResult Register(RegisterViewModel model)

in order for your server side ModelState.IsValid to work.



回答2:

[Key] public int Eno { get; set; }

    [DisplayName("Employee Name")]
    [Required(ErrorMessage = "Name is required")]
    [RegularExpression(@"^[a-zA-Z]+$",ErrorMessage = "Pls Enter Only Charaters")]
    [StringLength(100, MinimumLength = 3,ErrorMessage = "Name Length Minimun 3 is required")]
    public string Ename { get; set; }

    [DisplayName("Employee salary")]
    //[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:c}")]
    [RegularExpression(@"^[0-9]*$", ErrorMessage = "Pls Enter Only Numbers")]
    [Required(ErrorMessage = "salary is required")]
    [Range(3000, 10000000, ErrorMessage = "Salary must be between 3000 and 10000000")]
    public int salary { get; set; }


    [DisplayName("Image")]
    [Required(ErrorMessage = "Image is required")]
    public HttpPostedFileBase Image { get; set; }


    [DisplayName("Email")]
    [Required(ErrorMessage = "Email is required")]
    [RegularExpression(@"^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$", ErrorMessage ="Please Enter Valid EmailID")]
    public string Email { get; set; }


    [DisplayName("Password")]
    [Required(ErrorMessage = "Password is required")]
    [DataType(DataType.Password)]
    public string Password { get; set; }


    [DisplayName("ConfirmPassword")]
    [Required(ErrorMessage = "Password is required")]
    [Compare("Password", ErrorMessage = "Password is Not Matching")]
    public string ConfirmPassword { get; set; }


    [DisplayName("PHONENumber")]
    [Required(ErrorMessage = "PhoneNmber is required")]
    [RegularExpression(@"^[0-9]*$", ErrorMessage = "Pls Enter Only Numbers")]
    [StringLength(10,ErrorMessage ="maxlimit 10")]
    public string PhoneNmber { get; set; }



    [DisplayName("Age")]
    [RegularExpression(@"^[0-9]*$", ErrorMessage = "Pls Enter Only Numbers")]
    [Required(ErrorMessage = "Age is required")]
    public int Age { set; get; }


    [DisplayName("Gender")]
    [Required(ErrorMessage = "Gender is required")]
    public bool Gender { get; set; }


    [DisplayName("Date")]
    [Required(ErrorMessage = "Date is required")]
    public DateTime DateandTime { get; set; }

    [DisplayName("BookNames")]
    [Required(ErrorMessage = "Date is required")]
    public List<string> BookNames { get; set; }

}



回答3:

@{
    ViewBag.Title = "Registration";
    List<Books> BooksLists = (List<Books>)ViewBag.BooksList;
}

<h2>Registration</h2>

@*@using (Html.BeginForm())*@
@using (Html.BeginForm("Registration", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
    @Html.AntiForgeryToken()

<div class="form-horizontal">
    <h4>Employees</h4>
    <hr />
    @Html.ValidationSummary(true, "", new { @class = "text-danger" })
    <div class="form-group">
        @Html.LabelFor(model => model.Ename, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Ename, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.Ename, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.salary, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.salary, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.salary, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.Image, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.TextBoxFor(model => model.Image, new { @type = "file", @accept = "image/x-png,image/gif,image/jpeg" })   @*image/**@
            @Html.ValidationMessageFor(model => model.Image, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.Email, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Email, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.Email, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.Password, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Password, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.Password, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.ConfirmPassword, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.ConfirmPassword, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.ConfirmPassword, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.PhoneNmber, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @*@Html.EditorFor(model => model.PhoneNmber, new { htmlAttributes = new { @class = "form-control" } })*@
            @Html.TextBoxFor(model => model.PhoneNmber, "{0:c}", new { @class = "required numeric", id = "CurrentBalance" })
            @Html.ValidationMessageFor(model => model.PhoneNmber, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.Age, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Age, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.Age, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.Gender, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            <div class="checkbox">
                @*@Html.RadioButtonFor(m => m.Gender, "true") <label> Male </label>
                  @Html.RadioButtonFor(m => m.Gender, "false") <label> Female </label>*@

                @Html.DropDownListFor(model => model.Gender, new SelectList(new List<Object>{
                                     new { value = "" , text = "Select"  },
                                     new { value = 1 , text = "Male" },
                                     new { value = 0 , text = "Female"} }, "value", "text", 0))


                @Html.ValidationMessageFor(model => model.Gender, "", new { @class = "text-danger" })
            </div>
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.DateandTime, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.DateandTime, new { htmlAttributes = new { @class = "form-control", @type = "date" } })
            @Html.ValidationMessageFor(model => model.DateandTime, "", new { @class = "text-danger" })

        </div>
    </div>
   
    <div class="form-group">
        @Html.LabelFor(model => model.BookNames, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @if (Model != null)
            {
                for (int i = 0; i < @BooksLists.Count; i++)
                {
                    @Html.CheckBox(Convert.ToString(@BooksLists[i].BookName), false, new { @class = "ChkBooks", style = "margin-left: 20px;vertical-align: 1px;width: 16px;height: 16px; ", @type = "checkbox", @value = Convert.ToString(@BooksLists[i].BookId) })
                    @BooksLists[i].BookName;
                }
            }
            else
            {
                for (int i = 0; i < @BooksLists.Count(); i++)
                {
                    @Html.CheckBox(Convert.ToString(BooksLists[i].BookName), false, new { @class = "ChkBooks", style = "margin-left: 20px;vertical-align: 1px;width: 16px;height: 16px; ", @type = "checkbox", @value = Convert.ToString(@BooksLists[i].BookId) })
                    @BooksLists[i].BookName;
                }
            }
            <br />
            @Html.TextBoxFor(m => m.BookNames, new { @class = "form-control", style = "display: none",@readonly = true })
            @Html.ValidationMessageFor(model => model.BookNames, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        <div class="col-md-offset-2 col-md-10">
            <input type="submit" value="Create" class="btn btn-default" />
        </div>
    </div>
</div>
}



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



回答4:

  $(document).ready(function () {

        $(".ChkBooks").click(function () {
            var chkslst = $(".ChkBooks");
            var CheckedList = "";
            debugger;
            $.each(chkslst, function (index, data) {
                if (data.checked) {
                    CheckedList += data.value + ",";
                }
            });

            $("#BookNames").val(CheckedList);

        });
    });