تطبيق Validation في Model
-
في هذ الدرس بنتعلم شو المقصود في Model Validation وكيف تطبيقها، ويمكن القول ان Model Validation هي عملية للتأكد من أن البيانات المدخله في View مناسبة لربط Model. وفي حال تم ادخال بيانات خطأ، فسيتم عرض رسائل الخطأ المناسبة في View ، وسيساعد ذلك المستخدم على تصحيح المشكلة.
تمام خلونا نفهم الموضوع بتطبيق مثال.(تذكر ان طبقنا جزء من هذا الدرس في عمليات ADO.Net على جدول المواد والطلاب).
المثال هون بنطبق Validation على صفحة AddStudent. واكيد اذا بتذكر ان استخدمنا هذه الصفحة من قبل.
تمام نرجع نشغل التطبيق حتي نتذكر شكل الصفحه.
شغل التطبيق بالدخول الى الرابط:
https://localhost:44382/Students/NewStudent
انقر فوق Submit وشوف النتيجة.(اكيد بتلاحظ ان تم الانتقال الى AllStudent View).واكيد بتلاحظ ان ما صار اي تحقق من البيانات ولا في اي حقل اجباري يعن تم الانتقال الى الصفحة التالية وجميع الحقول فارغة واكيد هذا الاشي خطأ. وهاذي هي فكرة Validation.
ملاحظة: نوع input مربوط مع model يعني لو اخذنا المثال
<input class="form-control" asp-for="FullName" />
هاذا input مربوط مع Property الي اسمها FullName وتعريفها في model من نوع string
مثال ثاني :
<input class="form-control" asp-for="Birthday" asp-format="{0:d}" type="date" />
هذا input مربوط مع Property الي اسمها Birthday وتعريفها من نوع DateTime وهكذا.
تمام خلونا نتذكر الكود الكامل لملف NewStudent View:
@model StudentsModel
@{
Layout = null;
}
<meta name="viewport" content="width=device-width" />
<title>Index</title>
<style>
.input-validation-error {
border-color: red !important;
}
</style>
<link href="~/lib/bootstrap/css/bootstrap.min.css" rel="stylesheet" />
@*<link href="~/lib/bootstrap/css/bootstrap.css" rel="stylesheet" />*@
@*Welcome ,@TempData["UserName"]*@
Welcome,
<hr />
<div class="container">
<form id="" method="post" class="m-1 p-1">
<div class="form-group">
<div class="row">
<div class="col-2"><label>FullName:</label></div>
<div class="col-10">
<input asp-for="FullName" class="form-control" />
@*<span asp-validation-for="FullName" class="text-danger"></span>*@
</div>
</div>
</div>
<div class="form-group">
<div class="row">
<div class="col-2"> <label>Birthday:</label></div>
<div class="col-10">
<input class="form-control" asp-for="Birthday" asp-format="{0:d}" type="date" />
@*<span asp-validation-for="Birthday" class="text-danger"></span>*@
</div>
</div>
</div>
<div class="form-group">
<div class="row">
<div class="col-2"><label>Gender:</label></div>
<div class="col-10">
<select class="form-control" asp-for="Gender">
<option value="">--Select Gender--</option>
<option value="1">Male</option>
<option value="2">Female</option>
</select>
<span asp-validation-for="Gender" class="text-danger"></span>
</div>
</div>
</div>
<div class="form-group">
<div class="row">
<div class="col-2"> <label>Nationality:</label></div>
<div class="col-10">
<select class="form-control" asp-for="Nationality">
<option value="">--Select Nationality--</option>
<option value="1">Jordan</option>
<option value="2">Saudi Aribae</option>
<option value="3">UAE</option>
</select>
<span asp-validation-for="Nationality" class="text-danger"></span>
</div>
</div>
</div>
<div class="form-group">
<div class="row">
<div class="col-2"> <label>Address:</label></div>
<div class="col-10">
<input class="form-control" asp-for="Address" />
<span asp-validation-for="Address" class="text-danger"></span>
</div>
</div>
</div>
<div class="form-group">
<div class="row">
<div class="col-2"> <label>UserName:</label></div>
<div class="col-10">
<input class="form-control" asp-for="UserName" />
<span asp-validation-for="UserName" class="text-danger"></span>
</div>
</div>
</div>
<div class="form-group">
<div class="row">
<div class="col-2"> <label>Password:</label></div>
<div class="col-10">
<input class="form-control" asp-for="Password" />
<span asp-validation-for="Password" class="text-danger"></span>
</div>
</div>
</div>
<div class="form-group">
<div class="row">
<div class="col-2"><label>Email:</label></div>
<div class="col-10">
<input class="form-control" asp-for="Email" />
<span asp-validation-for="Email" class="text-danger"></span>
</div>
</div>
</div><div class="form-group">
<div class="row">
<div class="col-2"> <label>Mobile:</label></div>
<div class="col-10">
<input class="form-control" asp-for="Mobile" />
<span asp-validation-for="Mobile" class="text-danger"></span>
</div>
</div>
</div>
<div class="form-group">
<div class="row">
<div class="col-2"> <label>Note:</label></div>
<div class="col-10">
<input class="form-control" asp-for="Note" />
<span asp-validation-for="Note" class="text-danger"></span>
</div>
</div>
</div>
<button class="btn btn-primary" type="submit">Submit</button>
</form>
</div>
@*@{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); }*@
يمكن تطبيق Validation بطريقتين
1- على مستوى action نفسه بالتحقق من الحقول واحد تلو الاخر(اضافة كود برمجي لكل حقل)
2- على مستوى Model باستخدام Data Annotations
تمام نبدأ بأول مستوي وهي عن طريق action
بشكل عام يمكن القول ان هذه الطريقة يتم فيها كتابة كود، يعن بنتحقق من الحقول كلها بكتابة اكواد اذا كانت فارغة ام لا ونوع الحقول .
هون وحتي نعمل Validation لازم نعرف ان عندنا طريقتين لتحقيق هاذا الامر وهم:
- ()AddModelError
- ()ModelState.IsValid
الطريقة الأولى وهي ()AddModelError
يستخدم أسلوب ()AddModelError لتسجيل خطأ خلال التحقق من صحة النموذج لخاصية محددة specified property.
وتكتب بالشكل:
AddModelError(property, message);
تستخدم في النهاية بحيث ترجع true إذا كانت جميع خصائص النموذج صالحة وتعيد القيمة false في الحالات الأخرى.
طيب تمام نشوف كيف ممكن نطبق هذا الكلام في NewStudent action
المثال التالي بنطبق Validation على مجموعة حقول ومش كلها.
if (string.IsNullOrEmpty(studentsModel.FullName))
ModelState.AddModelError(nameof(studentsModel.FullName), "Please enter your name");
if (studentsModel.Birthday == Convert.ToDateTime("01-01-0001 00:00:00"))
ModelState.AddModelError(nameof(studentsModel.Birthday), "Please enter your Date of Birth");
else if (studentsModel.Birthday > DateTime.Now)
ModelState.AddModelError(nameof(studentsModel.Birthday), "Date of Birth cannot be in the future");
else if (studentsModel.Birthday < new DateTime(1950, 1, 1))
ModelState.AddModelError(nameof(studentsModel.Birthday), "Date of Birth should not be before 1950");
if (string.IsNullOrEmpty(studentsModel.Gender.ToString()))
ModelState.AddModelError(nameof(studentsModel.Gender), "Please select your Gender");
if (studentsModel.Nationality.ToString() == "--Select Nationality--")
ModelState.AddModelError(nameof(studentsModel.Nationality), "Please select your Nationality");
if (ModelState.IsValid)
{...}
else
{return View();}
if (string.IsNullOrEmpty(studentsModel.FullName))
ModelState.AddModelError(nameof(studentsModel.FullName), "Please enter your name");
عملنا تحقق من FullName اول اشي فحصنا القيمة ان ما تكون فاضيه ولا Null ، واذا كانت فاضيةempty او Null بنضيف الخطأ باستخدام
AddModelError مربوط في FullName Property مع ذكر الرسالة المطلوب عرضها علي الشاشة. وهي Please enter your name
التحقق من تاريخ الميلاد
استخدمنا الكود :
if (studentsModel.Birthday == Convert.ToDateTime("01-01-0001 00:00:00"))
ModelState.AddModelError(nameof(studentsModel.Birthday), "Please enter your Date of Birth");
else if (studentsModel.Birthday > DateTime.Now)
ModelState.AddModelError(nameof(studentsModel.Birthday), "Date of Birth cannot be in the future");
else if (studentsModel.Birthday < new DateTime(1950, 1, 1))
ModelState.AddModelError(nameof(studentsModel.Birthday), "Date of Birth should not be before 1950");
عملنا تحقق لتاريخ الميلاد اولا اذا كان يساوي القيمة 01-01-0001 00:00:00 وبنرجع خطأ برسالة Please enter your Date of Birth
التحقق الثاني اذا كان تاريخ الميلاد في المستقبل بنرجع الرسالة Date of Birth cannot be in the future وتحققنا من ذلك بفحص قيمة التاريخ المدخل اذا كان اكبر من التاريخ الحالي
التحقق الثالث اضافنا شرط ان الطلاب المسموح يسجلو معنا لازم يكون مواليد 1950 واكير اقل من هيك ممنوع
التحقق من الجنسية
if (studentsModel.Nationality.ToString() == "--Select Nationality--")
ModelState.AddModelError(nameof(studentsModel.Nationality), "Please select your Nationality");
اذا كانت القيمة المختارة تساوي --Select Nationality-- فهذا يعني ان ما تم تحديد الجنسيه.
وهكذا لبقية Property
اخر سطر في الكود استخدمنا الاوامر :
if (ModelState.IsValid)
{...}
else
{ return View(); }
هنا يتم التحقق من النتيجة النهائية لمعرفة ما إذا كانت هناك أخطاء. في حال وجودها يتم العوده الى نفس View وهي studentsModel، وفي حال عدم وجود أخطأ فهذا يعني تنفيذ كود ادخال الطالب.
تمام نجرب نشغل الصفحة ونشوف النتيجة، اكيد بتكون النتيجة ان كل ما حاولت تضغط على زر Submit ونشوف النتيجة.
اكيد بتكون بالشكل التالي:
لاحظ ان الحقول الى عملنا عليها validation تم اضافة اطار احمر حولها. تمام نفهم سبب هذا الاطار وكيف طلع.
في طريقة AddModelError في حال وجود خطأ يتم اضافة class باسم input-validation-error الى هذا element . اذا حاولنا عرض source code للصفحة اكيد بتلاحظ ان تم اضافة هذا class الى كل input الى عملنا عليها validation شوف الصورة :
ولاظهار الكود باللون الأحمر اضفنا كود CSS في اول View التالي:
<style>
.input-validation-error {
border-color: red !important;
}
</style>
عرض الأخطاء في asp-validation-summary
<div asp-validation-summary="All" class="text-danger"></div>

Description | Name |
يعرض جميع رسائل التحقق من الصحة المسجلة. | All |
يعرض فقط رسالة التحقق التي تم تسجيلها للنموذج بأكمله. يستثني رسائل التحقق من الصحة التي تم تسجيلها للخصائص الفردية. | ModelOnly |
لا يعرض أي رسالة تحقق | None |
<div class="form-group"><div class="row"><div class="col-2"><label>FullName:</label></div> <div class="col-10"> <input asp-for="FullName" class="form-control" /> <span asp-validation-for="FullName" class="text-danger"></span> </div> </div> </div>
@model StudentsModel
@{
Layout = null;
}
<meta name="viewport" content="width=device-width" />
<title>Index</title>
<style>
.input-validation-error {
border-color: red !important;
}
</style>
<link href="~/lib/bootstrap/css/bootstrap.min.css" rel="stylesheet" />
@*<link href="~/lib/bootstrap/css/bootstrap.css" rel="stylesheet" />*@
@*Welcome ,@TempData["UserName"]*@
Welcome,
<hr />
<div asp-validation-summary="All" class="text-danger"></div>
<div class="container">
<form id="" method="post" class="m-1 p-1">
<div class="form-group">
<div class="row">
<div class="col-2"><label>FullName:</label></div>
<div class="col-10">
<input asp-for="FullName" class="form-control" />
<span asp-validation-for="FullName" class="text-danger"></span>
</div>
</div>
</div>
<div class="form-group">
<div class="row">
<div class="col-2"> <label>Birthday:</label></div>
<div class="col-10">
<input class="form-control" asp-for="Birthday" asp-format="{0:d}" type="date" />
<span asp-validation-for="Birthday" class="text-danger"></span>
</div>
</div>
</div>
<div class="form-group">
<div class="row">
<div class="col-2"><label>Gender:</label></div>
<div class="col-10">
<select class="form-control" asp-for="Gender">
<option value="">--Select Gender--</option>
<option value="1">Male</option>
<option value="2">Female</option>
</select>
<span asp-validation-for="Gender" class="text-danger"></span>
</div>
</div>
</div>
<div class="form-group">
<div class="row">
<div class="col-2"> <label>Nationality:</label></div>
<div class="col-10">
<select class="form-control" asp-for="Nationality">
<option value="">--Select Nationality--</option>
<option value="1">Jordan</option>
<option value="2">Saudi Aribae</option>
<option value="3">UAE</option>
</select>
<span asp-validation-for="Nationality" class="text-danger"></span>
</div>
</div>
</div>
<div class="form-group">
<div class="row">
<div class="col-2"> <label>Address:</label></div>
<div class="col-10">
<input class="form-control" asp-for="Address" />
<span asp-validation-for="Address" class="text-danger"></span>
</div>
</div>
</div>
<div class="form-group">
<div class="row">
<div class="col-2"> <label>UserName:</label></div>
<div class="col-10">
<input class="form-control" asp-for="UserName" />
<span asp-validation-for="UserName" class="text-danger"></span>
</div>
</div>
</div>
<div class="form-group">
<div class="row">
<div class="col-2"> <label>Password:</label></div>
<div class="col-10">
<input class="form-control" asp-for="Password" />
<span asp-validation-for="Password" class="text-danger"></span>
</div>
</div>
</div>
<div class="form-group">
<div class="row">
<div class="col-2"><label>Email:</label></div>
<div class="col-10">
<input class="form-control" asp-for="Email" />
<span asp-validation-for="Email" class="text-danger"></span>
</div>
</div>
</div><div class="form-group">
<div class="row">
<div class="col-2"> <label>Mobile:</label></div>
<div class="col-10">
<input class="form-control" asp-for="Mobile" />
<span asp-validation-for="Mobile" class="text-danger"></span>
</div>
</div>
</div>
<div class="form-group">
<div class="row">
<div class="col-2"> <label>Note:</label></div>
<div class="col-10">
<input class="form-control" asp-for="Note" />
<span asp-validation-for="Note" class="text-danger"></span>
</div>
</div>
</div>
<button class="btn btn-primary" type="submit">Submit</button>
</form>
</div>
@*@{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); }*@

Description | Name |
يضمن أن القيمة ليست فارغة (اجباري ادخال قيمة). لا يمكن الاستمرار في حال لم يتم ادخال قيم | [Required(ErrorMessage = “Some Message”)] |
يضمن أن يكون طول String من القيم الدنيا إلى القصوى (تكون القيم بين min & max). مثال [StringLeght (2،5)] يسمح بان يكون طول String من 2 إلى 5. | [StringLength(max,min)] |
يضمن أن property التي يتم تطبيقه عليها مطابقة تمام لغيرها. مثال تستخدم عند طلب ادخال كلمة المرور مرتين(يجب ان تكون القيم متساوية) | [Compare(“OtherProperty”)] |
يضمن أن القيم العدديه( numeric) تقع من الحد الأدنى إلى الحد الأقصى مثال: [Range (2،5)] يسمح بالقيم من 2،3،4،5. | [Range(min,max)] |
يضمن تطابق القيم المدخله مع regular expression محدد. مثال التحقق عند ادخال عناوين البريد الإلكتروني. | [RegularExpression(“pattern”)] |
using System.ComponentModel.DataAnnotations;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;
namespace ModelBindingValidation.Models
{
public class StudentsModel
{
public int StudentID { get; set; }
public string StudentNo { get; set; }
[Required(ErrorMessage = "Please enter name")]
[StringLength(150)]
public string FullName { get; set; }
[Required(ErrorMessage = "Please enter Birthday")]
[DataType(DataType.DateTime)]
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:MM/dd/yyyy}")]
public DateTime Birthday { get; set; }
[Required(ErrorMessage = "Please enter Gender")]
public int Gender { get; set; }
[Required(ErrorMessage = "Please enter Nationality")]
public int Nationality { get; set; }
public string Address { get; set; }
[Required(ErrorMessage = "Please enter User Name")]
[StringLength(20)]
public string UserName { get; set; }
[Required(ErrorMessage = "Please enter Password")]
[StringLength(20)]
[DataType(DataType.Password)]
public string Password { get; set; }
[Required(ErrorMessage = "Confirm Password is required")]
[DataType(DataType.Password)]
[Compare("Password")]
public string ConfirmPassword { get; set; }
[Required(ErrorMessage = "Please enter Email")]
[RegularExpression("^[a-z0-9_\+-]+(\.[a-z0-9_\+-]+)*@[a-z0-9-]+(\.[a-z0-9]+)*\.([a-z]{2,4})$", ErrorMessage = "Invalid email format.")]
[StringLength(20)]
public string Email { get; set; }
[Required(ErrorMessage = "Mobile is required")]
[RegularExpression(@"d{10}", ErrorMessage = "Please enter 10 digit Mobile No.")]
public string Mobile { get; set; }
public string Note { get; set; }
public DateTime CreatedDate { get; set; }
public DateTime CurrentDate { get; set; }
public Address StudentAddress { get; set; }
}
}

[Required(ErrorMessage = "Please enter name")]
[StringLength(150)]
public string FullName { get; set; }
[Required]
[Display(Name = "Job applicant name")]
public string Name { get; set; }
[Required(ErrorMessage = "Please enter Email")]
[RegularExpression("^[a-z0-9_\\+-]+(\\.[a-z0-9_\\+-]+)*@[a-z0-9-]+(\\.[a-z0-9]+)*\\.([a-z]{2,4})$", ErrorMessage = "Invalid email format.")]
[StringLength(20)]public string Email { get; set; }
واضفنا الامر
[RegularExpression("^[a-z0-9_\\+-]+(\\.[a-z0-9_\\+-]+)*@[a-z0-9-]+(\\.[a-z0-9]+)*\\.([a-z]{2,4})$", ErrorMessage = "Invalid email format.")]
الي بيعني ان محتوي هذا الحقل يجب ان يكون من نوع Email
وطبقنا اخيرا الأمر :
[StringLength(20)]
الي بعين ان الطول يجب ان يكون يساوي 20 فقط ومش اكثر.
وهكذا بالنسبة للباقي.
اذا اردنا تطبيق هذا Validation على checkbox
[Range(typeof(bool), "true", "true", ErrorMessage = "You must accept the Terms")]
public bool TermsAccepted { get; set; }
اكيد بتلاحظ ان هذه الطريقة اسهل واسرع واقل كتابة كود. لكن في هذه الطريقة لا يمكن التحكم بكل شي ، مثلا في المثال السابق تحققنا من عمر المستخدم بان يكون اكبر من 1950 ، وان لا يكون اكبر من التاريخ الحالي، في مثل هذه الحالة لا يمكن تحقيق ذلك باستخدام هذه الطريقة فيكون اجباري كتابة الكود السابق.
تمام وهيك بتكون طبقنا validation
اترك تعليقك