Reputation: 840
I'm creating a project using ASP.Net MVC 4, Bootstrap 3, EF6 and AdventureWorks database. EF models are generated using database first approach. In the product form that I'm creating, all fields are required, however, some of the fields are getting validation errors, others are not. All the text fields are not getting validation errors, while all numeric fields are showing the validation error correctly. Here is an image:
Here is my view:
<h2>Add A Product</h2>
<div class="container">
@using (Html.BeginForm())
{
<div class="row">
<div class="col-md-3">@Html.LabelFor(model => model.Name, new { @class = "form-control" })</div>
<div class="col-md-6">
@Html.TextBoxFor(model => model.Name, new { @class = "form-control" })
@Html.ValidationMessageFor(model=>model.Name)
</div>
</div>
<div class="row">
<div class="col-md-3">@Html.LabelFor(model => model.ProductNumber, new { @class = "form-control" })</div>
<div class="col-md-6">
@Html.TextBoxFor(model => model.ProductNumber, new { @class = "form-control" })
@Html.ValidationMessageFor(model => model.ProductNumber)
</div>
</div>
<div class="row">
<div class="col-md-3">@Html.LabelFor(model => model.MakeFlag, new { @class = "form-control" })</div>
<div class="col-md-3">@Html.CheckBoxFor(model => model.MakeFlag, new { @class = "checkbox" })</div>
</div>
<div class="row">
<div class="col-md-3">@Html.LabelFor(model => model.FinishedGoodsFlag, new { @class = "form-control" })</div>
<div class="col-md-3">@Html.CheckBoxFor(model => model.FinishedGoodsFlag, new { @class = "checkbox" })</div>
</div>
<div class="row">
<div class="col-md-3">@Html.LabelFor(model => model.Color, new { @class = "form-control" })</div>
<div class="col-md-6">
@Html.TextBoxFor(model => model.Color, new { @class = "form-control" })
@Html.ValidationMessageFor(model => model.Color)
</div>
</div>
<div class="row">
<div class="col-md-3">@Html.LabelFor(model => model.SafetyStockLevel, new { @class = "form-control" })</div>
<div class="col-md-6">
@Html.TextBoxFor(model => model.SafetyStockLevel, new { @class = "form-control" })
@Html.ValidationMessageFor(model => model.SafetyStockLevel)
</div>
</div>
<div class="row">
<div class="col-md-3">@Html.LabelFor(model => model.ReorderPoint, new { @class = "form-control" })</div>
<div class="col-md-6">
@Html.TextBoxFor(model => model.ReorderPoint, new { @class = "form-control" })
@Html.ValidationMessageFor(model=>model.ReorderPoint)
</div>
</div>
<div class="row">
<div class="col-md-3">@Html.LabelFor(model => model.StandardCost, new { @class = "form-control" })</div>
<div class="col-md-6">
@Html.TextBoxFor(model => model.StandardCost, new { @class = "form-control" })
@Html.ValidationMessageFor(model => model.StandardCost)
</div>
</div>
<div class="row">
<div class="col-md-3">@Html.LabelFor(model => model.ListPrice, new { @class = "form-control" })</div>
<div class="col-md-6">
@Html.TextBoxFor(model => model.ListPrice, new { @class = "form-control" })
@Html.ValidationMessageFor(model => model.ListPrice)
</div>
</div>
<div class="row">
<div class="col-md-3">@Html.LabelFor(model => model.DaysToManufacture, new { @class = "form-control" })</div>
<div class="col-md-6">
@Html.TextBoxFor(model => model.DaysToManufacture, new { @class = "form-control" })
@Html.ValidationMessageFor(model => model.DaysToManufacture)
</div>
</div>
<div class="row">
<div class="col-md-3">@Html.LabelFor(model => model.SellStartDate, new { @class = "form-control" })</div>
<div class="col-md-6">
@Html.TextBoxFor(model => model.SellStartDate, new { @class = "form-control datepicker", placeholder = "Enter sell start date here..." })
@Html.ValidationMessageFor(model => model.SellStartDate)
</div>
</div>
<div class="row">
<div class="col-md-6">
<button type="submit" class="btn btn-info col-md-2">Submit</button>
</div>
</div>
}
</div>
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
@*@Scripts.Render("~/bundles/jquery-ui")*@
<script src="~/Scripts/jquery-ui-1.11.4.min.js"></script>
<script type="text/javascript">
$('.datepicker').datepicker(); //Initialise any date pickers
</script>
<script>
$(document).ready(function () { $(".datepicker").datepicker({}); });
</script>
}
My model is the default EF model without any [Required] annotations for any field:
public int ProductID { get; set; }
public string Name { get; set; }
public string ProductNumber { get; set; }
public bool MakeFlag { get; set; }
public bool FinishedGoodsFlag { get; set; }
public string Color { get; set; }
public short SafetyStockLevel { get; set; }
public short ReorderPoint { get; set; }
public decimal StandardCost { get; set; }
public decimal ListPrice { get; set; }
public string Size { get; set; }
public string SizeUnitMeasureCode { get; set; }
public string WeightUnitMeasureCode { get; set; }
public Nullable<decimal> Weight { get; set; }
public int DaysToManufacture { get; set; }
public string ProductLine { get; set; }
public string Class { get; set; }
public string Style { get; set; }
public Nullable<int> ProductSubcategoryID { get; set; }
public Nullable<int> ProductModelID { get; set; }
public System.DateTime SellStartDate { get; set; }
public Nullable<System.DateTime> SellEndDate { get; set; }
public Nullable<System.DateTime> DiscontinuedDate { get; set; }
public System.Guid rowguid { get; set; }
public System.DateTime ModifiedDate { get; set; }
Nullable property of all text field is set to false:
Why numeric fields are getting validate while strings are not?
Upvotes: 1
Views: 60
Reputation: 91
They are defined in the database "NO-NULL".
Recommendation:
using System.ComponentModel.DataAnnotations;
[Required]
[Display(Name = "Days To Manufacture")]
public int DaysToManufacture { get; set; }
Upvotes: 1
Reputation: 93464
To expand on @ErikPhilips answer.
.NET has Value types and Reference types. Numeric values are typically Value types, such as int, double, etc.. Strings are reference types.
A Value type must have a value (ie, it cannot be null) and the MVC framework enforces this by making a value type required, regardless of whether there is a required attribute on it. In other words, you cannot assign null to an int or double, and thus MVC throws the error.
This is why some values are being validated (value types) and some are not (reference types). You will note that some of your value types are wrapped in Nullable wrappers, those types will also not be validated in.
Upvotes: 2
Reputation: 54636
Some form fields are getting validation messages others are not?
Property types that are not nullable (int, decimal, short, bool, etc) require a value (null/empty string cannot be parsed into a default value) . string
is nullable by default so it does not have to have a value. It's really that simple.
Upvotes: 1
Reputation: 558
First of all you should not use your EF Model as a view model. Instead create a new view model with the properties you need for your form. After that decorated the properties, which should be required with a [Required]
tag.
Furthermore, don't forget to check the model state in your controller action, which receives the form data, because JavaScript validation does not protect you from receiving invalid form data.You can do this with the following code:
if(ModelState.IsValid)
{
//do some stuff with form data
}
else
return View(viewModel);
If you wanna learn more about validation in MVC, you can read this post
Upvotes: 1