65.9K
CodeProject 正在变化。 阅读更多。
Home

7 天学习 MVC 项目 - 第 4 天

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.91/5 (122投票s)

2015年6月2日

CPOL

16分钟阅读

viewsIcon

427000

downloadIcon

26022

本文是“7天学会MVC项目”系列文章的第4天内容的延续。

引言

欢迎来到“7天学会MVC项目”系列的第4天。如果您直接阅读本文,我强烈建议您先完成该系列的所有前几部分,然后再继续阅读。

完整系列

我们很高兴地宣布,本文现已出版纸质书,您可以在 www.amazon.comwww.flipkart.com 购买。

议程

实验 15 – 验证错误后保留值
关于实验 15 的讨论
实验 16 – 添加客户端验证
关于实验 16 的讨论
实验 17 – 添加身份验证
关于实验 17 的讨论
实验 18 – 在视图中显示用户名
实验 19 – 实现注销
实验 20 – 在登录页面实现验证
实验 21 – 在登录页面实现客户端验证
关于实验 21 的讨论
结论

实验 15 – 验证错误后保留值

在实验 13 中,我们介绍了服务器端验证,在实验 14 中,我们通过添加自定义验证支持将其提升到了一个新的水平。

我强烈建议您再次回顾实验 14。执行它,并完美理解代码和输出。

在实验 15 中,我们将学习如何在验证失败时重新填充值。

步骤 1 - 创建 CreateEmployeeViewModel

在 ViewModel 文件夹中创建一个新类,如下所示。

public class CreateEmployeeViewModel
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Salary { get; set; }
}

步骤 2 – 修改 SaveEmployee 操作方法

为了重新填充,我们将简单地重用 Model Binder 创建的 Employee 对象。修改 SaveEmployee 操作方法如下。

public ActionResult SaveEmployee(Employee e, string BtnSubmit)
{
    switch (BtnSubmit)
    {
        case "Save Employee":
            if (ModelState.IsValid)
            {
                EmployeeBusinessLayer empBal = new EmployeeBusinessLayer();
                empBal.SaveEmployee(e);
                return RedirectToAction("Index");
            }
            else
            {
                CreateEmployeeViewModel vm = new CreateEmployeeViewModel();
                vm.FirstName = e.FirstName;
                vm.LastName = e.LastName;
                if (e.Salary.HasValue)
                {
                    vm.Salary = e.Salary.ToString();                        
                }
                else
                {
                    vm.Salary = ModelState["Salary"].Value.AttemptedValue;                       
                }
                return View("CreateEmployee", vm); // Day 4 Change - Passing e here
            }
        case "Cancel":
            return RedirectToAction("Index");
    }
    return new EmptyResult();
}

步骤 3 – 在视图中重新填充值

步骤 3.1 使视图成为强类型视图

在 CreateEmployee 视图的顶部放入以下代码。

@using WebApplication1.ViewModels
@model CreateEmployeeViewModel

步骤 3.2 从模型中在相应的控件中显示值

...

...

...

<input type="text" id="TxtFName" name="FirstName" value="@Model.FirstName" />

...

...

...

<input type="text" id="TxtLName" name="LastName" value="@Model.LastName" />

...

...

...

<input type="text" id="TxtSalary" name="Salary" value="@Model.Salary" />

...

...

...

步骤 4 – 执行和测试

按 F5 执行应用程序。通过单击“添加新”链接导航到 AddNew 屏幕。

此错误的根本原因将在本次实验结束时讨论。现在让我们实现解决方案。

步骤 5 – 修改 AddNew 操作方法

public ActionResult AddNew()
{
    return View("CreateEmployee”, new CreateEmployeeViewModel());
}

步骤 6 – 执行和测试

按 F5 并执行应用程序。

测试1

  • 通过单击“添加新”链接导航到 AddNew 屏幕。
  • 保持名字为空
  • 将工资设置为 56。
  • 单击“保存员工”按钮。

这将导致两个验证失败

正如您所看到的,56 保留在了工资文本框中。

测试2

正如您所看到的,名字和姓氏文本框的值已保留。

奇怪的是工资没有保留。我们将在本次实验结束时讨论原因和解决方案。

关于实验 15 的讨论

我们真的在这里保留值吗?

不,我们没有。这里我们实际上是从已发布的(posted)数据中重新填充值的。

为什么在初始请求(即“添加新”操作方法)中需要传递“new CreateEmployeeViewModel()”?

在视图中,我们尝试用模型中的值填充文本框。

示例

<input id="TxtSalary" name="Salary" type="text" value="@Model.Salary" />

正如您所看到的,在上面的代码块中,我们正在访问当前模型的 FirstName 属性。如果模型为 null,则会抛出“未将对象引用设置到对象的实例”异常。

当单击“添加新”超链接时,请求将由“添加新”操作方法处理。先前在此操作方法中,我们返回了视图而未传递任何数据。这意味着视图内的 Model 属性将为 Null,而 Null.Something 将抛出“未将对象引用设置到对象的实例”异常。为了解决这些问题,“new CreateEmployeeViewModel()”是在初始请求期间传递的。

我们有任何自动实现相同功能的办法吗?

是的,我们可以使用 HTML 辅助类来实现。我们将在接下来的一个实验中讨论这个问题。

实验 16 – 添加客户端验证

首先,让我们列出我们需要的所有验证。

  1. 名字不应为空。
  2. 姓氏长度不应大于 5。
  3. 工资不应为空。
  4. 工资应为正确的数字。
  5. 名字不应包含“@”符号。

让我们看看如何实现它。

步骤 1 – 创建 JavaScript 验证文件

创建一个名为“Validations.js”的 JavaScript 文件,并将其放在 Scripts 文件夹中。

步骤 2 – 创建验证函数

在“Validations.js”文件中,创建如下验证函数。

function IsFirstNameEmpty() {
    if (document.getElementById('TxtFName').value == "") {
        return 'First Name should not be empty';
    }
    else { return ""; }
}

function IsFirstNameInValid() {    
    if (document.getElementById('TxtFName').value.indexOf("@") != -1) {
        return 'First Name should not contain @';
    }
    else { return ""; }
}
function IsLastNameInValid() {
    if (document.getElementById('TxtLName').value.length>=5) {
        return 'Last Name should not contain more than 5 character';
    }
    else { return ""; }
}
function IsSalaryEmpty() {
    if (document.getElementById('TxtSalary').value=="") {
        return 'Salary should not be empty';
    }
    else { return ""; }
}
function IsSalaryInValid() {
    if (isNaN(document.getElementById('TxtSalary').value)) {
        return 'Enter valid salary';
    }
    else { return ""; }
}
function IsValid() {

    var FirstNameEmptyMessage = IsFirstNameEmpty();
    var FirstNameInValidMessage = IsFirstNameInValid();
    var LastNameInValidMessage = IsLastNameInValid();
    var SalaryEmptyMessage = IsSalaryEmpty();
    var SalaryInvalidMessage = IsSalaryInValid();

    var FinalErrorMessage = "Errors:";
    if (FirstNameEmptyMessage != "")
        FinalErrorMessage += "\n" + FirstNameEmptyMessage;
    if (FirstNameInValidMessage != "")
        FinalErrorMessage += "\n" + FirstNameInValidMessage;
    if (LastNameInValidMessage != "")
        FinalErrorMessage += "\n" + LastNameInValidMessage;
    if (SalaryEmptyMessage != "")
        FinalErrorMessage += "\n" + SalaryEmptyMessage;
    if (SalaryInvalidMessage != "")
        FinalErrorMessage += "\n" + SalaryInvalidMessage;

    if (FinalErrorMessage != "Errors:") {
        alert(FinalErrorMessage);
        return false;
    }
    else {
        return true;
    }
}

步骤 3 - 在视图中包含验证文件

只需在“CreateEmployee”视图的 head 部分添加“Validations.js”文件的引用,如下所示。

<script src="~/Scripts/Validations.js"></script>

步骤 4 – 附加验证

只需在单击 SaveEmployee 按钮时调用 IsValid 函数,如下所示。

<input type="submit" name="BtnSubmit" value="Save Employee" onclick="return IsValid();" />

第五步——执行和测试

按 F5 执行应用程序。

通过单击“添加新”链接导航到 AddNew 屏幕。

测试1

测试2

关于实验 16 的讨论

为什么在 SaveEmployee 按钮的 onclick 事件中需要 return 关键字?

正如我们在实验 9 中讨论过的,提交按钮在单击时会向服务器发出请求。当验证失败时,没有理由发出服务器请求。通过在提交按钮的 onclick 事件中编写“return false”,我们可以阻止默认的服务器请求。

在我们的例子中,当验证失败时,IsValid 函数将返回 false,从而实现所需的功能。

能否在页面本身显示错误消息,而不是使用 alert?

可以。只需为每个错误创建一个 span 标签。最初将其设置为不可见(使用 CSS),在单击提交按钮时,如果验证失败,则使用 JavaScript 使其可见。

有没有办法自动获得这种客户端验证?

是的,当我们使用 HTML 助手时,可以基于服务器端验证实现自动客户端验证。我们将在未来的某个实验中讨论这个问题。

还需要服务器端验证吗?

是的,如果有人禁用了 JavaScript,服务器端验证将保持一切正常。

实验 17 – 添加身份验证

在此实验中,我们将保护我们的 GetView 操作方法。我们将确保只有有效用户才能访问该操作方法。

在本次系列的第 1 天,我们理解了 ASP.NET 和 MVC 一词的真正含义。我们了解到 ASP.NET MVC 是 ASP.NET 的一部分。ASP.NET 的大多数功能都继承到了 ASP.NET MVC 中。其中一项功能是表单身份验证。

在我们开始实验之前,先了解表单身份验证在 ASP.NET 中的工作原理。

  1. 最终用户通过浏览器向启用表单身份验证的应用程序发出请求。
  2. 浏览器将发送客户端计算机上存储的所有关联 cookie 到请求中。
  3. 当服务器端接收到请求时,服务器会检查请求并查找名为“Authentication Cookie”的特殊 cookie。
  4. 如果找到有效的身份验证 cookie,服务器将确认用户的身份,或者简单地说,将用户视为有效用户,并允许其继续。
  5. 如果找不到有效的身份验证 cookie,服务器将用户视为匿名(或未经身份验证)用户。在这种情况下,如果请求的资源被标记为受保护/安全,用户将被重定向到登录页面。

步骤 1 – 创建 AuthenticationController 和 Login 操作方法。

右键单击控制器文件夹,选择“添加新控制器”,并创建一个名为“Authentication”的控制器。在这种情况下,完整的类名将是“AuthenticationController”。

在控制器内部,创建一个名为 Login 的操作方法,如下所示。

public class AuthenticationController : Controller
{
    // GET: Authentication
    public ActionResult Login()
    {
        return View();
    }
}

步骤 2 – 创建模型

在 Models 文件夹中创建一个名为 UserDetails 的新模型类,如下所示。

namespace WebApplication1.Models
{
    public class UserDetails
    {
        public string UserName { get; set; }
        public string Password { get; set; }
    }
}

步骤 3 – 创建 Login 视图

在“~/Views/Authentication”文件夹中创建一个名为 Login 的新视图。使其成为 UserDetails 类型的强类型视图。

将以下 HTML 放入视图中。

@model WebApplication1.Models.UserDetails

@{

    Layout = null;

}

<!DOCTYPE html>

<html>

<head>

    <meta name="viewport" content="width=device-width" />

    <title>Login</title>

</head>

<body>

    <div>

        @using (Html.BeginForm("DoLogin", "Authentication", FormMethod.Post))

        {

            @Html.LabelFor(c=>c.UserName)

            @Html.TextBoxFor(x=>x.UserName)

           

            <br />

            @Html.LabelFor(c => c.Password)

            @Html.PasswordFor(x => x.Password)

            <br />


            <input type="submit" name="BtnSubmit" value="Login" />

        }

    </div>

</body>

</html>

正如您所看到的,这次我们使用 HtmlHelper 类来生成视图,而不是纯 HTML。

  • 在视图中,我们将获得一个名为“Html”的现成 HtmlHelper 类对象。
  • HtmlHelper 类函数简单地返回 html 字符串。

示例 1

@Html.TextBoxFor(x=>x.UserName)

上面的代码将生成以下 HTML。

<input id="UserName" name="UserName" type="text" value="" />

示例 2

@using (Html.BeginForm("DoLogin", "Authentication", FormMethod.Post))
{
}

上面的代码将生成以下 HTML。

<form action="/Authentication/DoLogin" method="post">
</form>

<form action="/Authentication/DoLogin" method="post"> <

步骤 4 – 执行和测试

按 F5 执行应用程序。在地址栏输入 Login 操作方法的 URL。在我的例子中,它将是“https://:8870/Authentication/Login”。

步骤 5 – 启用表单身份验证

打开 Web.config 文件。导航到 System.Web 部分。查找名为 Authentication 的子节。如果不存在,请创建它。将 Authentication 模式设置为 Forms,将 Login URL 设置为步骤 1 中创建的“Login”操作方法。


<forms loginurl="~/Authentication/Login"></forms>

步骤 6 – 保护操作方法。

打开 EmployeeController 并为 Index 操作添加 Authorize 属性,如下所示。

[Authorize]
public ActionResult Index()
{
    EmployeeListViewModel employeeListViewModel = new EmployeeListViewModel();
......

步骤 7 – 执行和测试

按 F5 执行应用程序。在地址栏输入 EmployeeController 的 Index 操作的 URL。在我的例子中,它将是“https://:8870/Employee/Index”。

正如您所看到的,对 Index 操作的请求已自动重定向到登录操作。

步骤 8 – 创建业务层功能

打开 EmployeeBusinessLayer 类并创建一个名为 IsValidUser 的方法,如下所示。

public bool IsValidUser(UserDetails u)
{
    if (u.UserName == "Admin" && u.Password == "Admin")
    {
        return true;
    }
    else
    {
        return false;
    }
}

注意:在业务层中,我们将用户名和密码与硬编码值进行比较。在实际应用中,我们可以调用数据库层并与实时值进行比较。

步骤 9 – 创建 DoLogin 操作方法

打开 AuthenticationController 类并创建一个名为 DoLogin 的新操作方法。

当单击 Login 视图中的 Login 按钮时,将调用此 DoLogin 操作方法(参见步骤 3)。

现在让我们列出需要在 DoLogin 中完成的点。

  1. 通过调用业务层函数检查用户有效性。
  2. 如果用户是有效用户,则创建一个身份验证 cookie。它使将来的请求成为经过身份验证的请求。
  3. 如果用户无效,则向当前 ModelState 添加一个新错误。此错误将在视图中显示。
[HttpPost]
public ActionResult DoLogin(UserDetails u)
{
    EmployeeBusinessLayer bal = new EmployeeBusinessLayer();
    if (bal.IsValidUser(u))
    {
        FormsAuthentication.SetAuthCookie(u.UserName, false);
        return RedirectToAction("Index", "Employee");
    }
    else
    {
        ModelState.AddModelError("CredentialError", "Invalid Username or Password");
        return View("Login");
    }
}

让我们来理解上面的代码块。

  • 如果您还记得在“第 3 天 – 实验 13”中,我们谈到了 ModelState,并理解它封装了模型当前的状态。它包含与当前模型相关的所有错误。在上面的代码片段中,当用户是无效用户时(键为“CredentialError”,消息为“无效用户名或密码”的新错误),我们添加了一个新错误。
  • FormsAuthentication.SetAuthCookie 将在客户端计算机上创建一个新 cookie。

步骤 10 – 在视图中显示消息

打开 Login 视图,在 @Html.BeginForm 上方添加以下代码。

@Html.ValidationMessage("CredentialError", new {style="color:red;" })
@using (Html.BeginForm("DoLogin", "Authentication", FormMethod.Post))
{

步骤 11 – 执行和测试

按 F5 执行应用程序。直接请求 Login 操作。我相信您现在知道如何操作了。

注意:如果您愿意,您可以请求 EmployeeController 的 Index 操作,但它最终会将您重定向到 Login 操作。

测试1

测试2

关于实验 17 的讨论

为什么 DoLogin 附加了 HttpPost 属性?

此属性使 DoLogin 操作方法仅对 Post 请求开放。如果有人尝试对 DoLogin 发出 get 请求,它将不起作用。

还有更多这样的属性吗?

是的。我们有 HttpGet、HttpPut 和 HttpDelete。作为最佳实践,每个操作方法都应附加此类属性。

注意:为了保持编码和学习简单易懂,本系列中我们并未处处遵循此做法,但我建议您在项目中严格遵循。

随着我们继续前进,我们将继续讨论这些最佳实践。

必须编写 FormsAuthentication.SetAuthCookie 吗?

是的。

让我们来理解一个小过程。

  • 客户端通过浏览器向服务器发出第一个请求。
  • 当通过浏览器发出请求时,所有关联的 cookie 都将随请求一起发送。
  • 服务器接收请求并准备响应。
  • 现在,我们知道请求-响应是通过 HTTP 协议进行的,而 HTTP 是一种无状态协议。对于服务器来说,每个请求都是一个新的请求,因此当同一客户端发出第二个请求时,服务器将无法识别它。为了解决这个问题,服务器将在准备好的响应中添加一个 cookie 并发回。
  • 当客户端浏览器收到带有 cookie 的响应时,它会在客户端计算机上创建 cookie。
  • 现在,如果客户端再次发出请求,服务器将能够识别他/她,因为请求中包含 cookie。

FormsAuthentication.SetAuthCookie 将一个名为“Authentication”的特殊 cookie 添加到响应中。

这是否意味着没有 cookie,FormsAuthentication 就无法工作?

不。我们有替代方案。我们可以使用 URI 而不是 cookie。

打开 Web.Config 并如下修改“Authentication/Forms”部分。

<forms cookieless="UseUri" loginurl="~/Authentication/Login"></forms>

正如您所看到的,现在身份验证 cookie 已经包含在 URL 中了。

默认情况下,cookieless 属性设置为“AutoDetect”。这意味着身份验证通过 cookie 进行,如果不支持 cookie,URL 将完成所需的工作。

FormsAuthentication.SetAuthCookie 的第二个参数做什么?

它决定我们是否要创建一个持久性 cookie。非持久性 cookie 在浏览器关闭时会自动删除。持久性 cookie 不会自动删除。我们必须通过编码或使用浏览器设置手动删除它们。

如何通过编码实现注销?

我们将在未来的某个实验中学习。

为什么在凭据错误时用户名文本框会重新填充?

这是 HTML 辅助类的魔力。它们会从已发布的(posted)数据中将值重新填充到控件中。这是使用助手类的一个优点。

@Html.ValidationMessage 的作用是什么?

我们在实验 13 的讨论中已经讲过。它根据键显示 ModelState 错误。

Authorize 属性有什么作用?

在 Asp.net MVC 中,有一个称为 Filters 的概念。它用于过滤请求和响应。有四种类型的过滤器。我们将在 7 天的旅程中逐一讨论它们。Authorize 属性属于 Authorization filter。它将确保只有经过身份验证的请求才能用于操作方法。

可以将 HttpPost 和 Authorize 属性同时附加到同一个操作方法上吗?

可以。

为什么这个例子中没有 ViewModel?

根据我们在实验 6 中的讨论,视图不应直接连接到模型。我们必须始终在视图和模型之间有一个 ViewModel。视图是简单的“显示视图”还是“数据录入视图”并不重要,它应该始终连接到 ViewModel。本项目中未使用的原因是简洁。在实际项目中,我强烈建议您到处使用 ViewModel。

是否必须将 Authorize 属性附加到每个操作方法上?

不。我们也可以将其附加到 Controller 级别或 Global 级别。当附加到 Controller 级别时,它将适用于 Controller 中的所有操作方法。当附加到 Global 级别时,它将适用于所有 Controller 中所有操作方法。

Controller 级别

[Authorize]
public class EmployeeController : Controller
{
....

全局级别

步骤 1 - 打开 App_start 文件夹中的 FilterConfig.cs 文件。

步骤 2 - 像下面这样添加另一行 RegisterGlobalFilters。

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
    filters.Add(new HandleErrorAttribute());//Old line
    filters.Add(new AuthorizeAttribute());//New Line
}

步骤 3 - 将 AllowAnonymous 属性附加到 Authentication controller。

[AllowAnonymous]
public class AuthenticationController : Controller
{

步骤 4 – 以前面的方式执行和测试应用程序。

filters.Add(new HandleErrorAttribute()) 的作用是什么?

我们将在未来的某个实验中详细讨论。

为什么 AuthenticationController 需要 AllowAnonymous 属性?

我们在全局级别附加了 Authorize filter。这意味着现在所有内容都受到保护,包括 Login 和 DoLogin 操作方法。AllowAnonymous 允许非身份验证的请求访问操作方法。

FilterConfig 类中的 RegisterGlobalFilters 方法是如何被调用的?

它在 Global.asax 文件中编写的 Application_Startevent 中被调用。

实验 18 – 在视图中显示用户名。

在本次实验中,我们将显示当前登录的用户名。

步骤 1 – 在 ViewModel 中添加 UserName

打开 EmployeeListViewModel 并添加一个名为 UserName 的新属性,如下所示。

public class EmployeeListViewModel
{
    public List<EmployeeViewModel> Employees { get; set; }
    public string UserName { get; set; }
}

步骤 2 – 为 ViewModel 的 UserName 设置值

打开 EmployeeController 并修改 Index,如下所示。

public ActionResult Index()
{
    EmployeeListViewModel employeeListViewModel = new EmployeeListViewModel();
    employeeListViewModel.UserName = User.Identity.Name; //New Line
......

步骤 3 – 在视图中显示 UserName

打开 Index.cshtml 视图并按如下方式显示 UserName。

<body>

  <div style="text-align:right"> Hello, @Model.UserName </div>

  <hr />

  <a  href="/Employee/AddNew">Add New</a>

    <div>

       <table border="1"> 
步骤 4 – 执行和测试

按 F5 执行应用程序。完成登录过程,您将看到以下输出。

实验 19 – 实现注销

步骤 1 – 创建注销链接

打开 Index.cshtml 并按如下方式创建注销链接。

<body>

    <div style="text-align:right">Hello, @Model.UserName

    <a href="/Authentication/Logout">Logout</a></div>

    <hr />

    <a  href="/Employee/AddNew">Add New</a>

    <div>

        <table border="1">
 

步骤 2 – 创建 Logout 操作方法。

打开 AuthenticationController 并按如下方式添加名为 Logout 的新操作方法。

public ActionResult Logout()
{
    FormsAuthentication.SignOut();
    return RedirectToAction("Login");
}

步骤 3 – 执行和测试

按 F5 执行应用程序。

实验 20 – 在登录页面实现验证

步骤 1 – 添加数据注解

打开 UserDetails.cs 并按如下方式添加数据注解。

public class UserDetails
{

[StringLength(7,MinimumLength=2, ErrorMessage = "UserName length should be between 2 and 7")]
    public string UserName { get; set; }
    public string Password { get; set; }
}

步骤 2 – 在视图中显示错误消息

修改 Login.cshtml 以显示错误消息。

@using (Html.BeginForm("DoLogin", "Authentication", FormMethod.Post))
{
    @Html.LabelFor(c=>c.UserName)
    @Html.TextBoxFor(x=>x.UserName)
    @Html.ValidationMessageFor(x=>x.UserName)
......

注意:这次我们使用了 Html.ValidationMessageFor 而不是 Html.ValidationMessage。两者都可以完成相同的事情。只有当视图是强类型视图时,才能使用 Html.ValidationMessageFor。

步骤 3 – 修改 DoLogin

如下修改 DoLogin 操作方法。

[HttpPost]
public ActionResult DoLogin(UserDetails u)
{
    if (ModelState.IsValid)
    {
        EmployeeBusinessLayer bal = new EmployeeBusinessLayer();
        if (bal.IsValidUser(u))
        {
            FormsAuthentication.SetAuthCookie(u.UserName, false);
            return RedirectToAction("Index", "Employee");
        }
        else
        {
            ModelState.AddModelError("CredentialError", "Invalid Username or Password");
            return View("Login");
        }
    }
    else
    {
        return View("Login");
    }
}

步骤 4- 执行和测试

按 F5 并执行应用程序。

实验 21 – 在登录页面实现客户端验证

这次我们将以不同的方式进行客户端验证。

步骤 1 – 下载 jQuery unobtrusive Validation 文件。

右键单击项目。选择“管理 NuGet 程序包”。

单击在线并搜索“jQuery Unobtrusive”。

安装“Microsoft jQuery Unobtrusive Valiadtion”。

步骤 2 – 在视图中包含 jQuery Validation 文件

上述步骤将三个 JavaScript 文件添加到 Scripts 文件夹中。

  • jQuery-Someversion.js
  • jQuery.valiadte.js
  • jquery.validate.unobtrusive

打开 Login.cshtml,在 head 部分包含所有三个 js 文件(按相同顺序)。

<script src="~/Scripts/jquery-1.8.0.js"></script>
<script src="~/Scripts/jquery.validate.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.js"></script>

步骤 3 – 执行和测试。

按 F5 并执行应用程序。

关于实验 21 的讨论

客户端验证是如何实现的?

正如您所看到的,在不费吹灰之力的情况下就实现了客户端验证。在 Login 视图中,HTML 元素是使用 HTML 辅助类生成的。助手函数在生成 HTML 标记时,会根据使用的数据注解属性附加一些属性。

示例

@Html.TextBoxFor(x=>x.UserName)
@Html.ValidationMessageFor(x=>x.UserName)

上面的代码将生成以下 HTML。

<input data-val="true" data-val-length="UserName length should be between 2 and 7" data-val-length-max="7" data-val-length-min="2" id="UserName" name="UserName" type="text" value="" />
 

这些自定义 HTML 属性将由“jQuery Unobtrusive validation files”使用,从而在客户端自动实现验证。

自动客户端验证是 HTML 辅助类的第二个优点。

什么是 unobtrusive JavaScript?

维基百科对此是这样说的。

Unobtrusive JavaScript 是一种通用的 JavaScript 在网页中的使用方法。虽然这个术语没有正式定义,但其基本原则通常包括
  • 将功能(“行为层”)与网页的结构/内容和演示分开
  • 最佳实践,避免传统 JavaScript 编程的问题(如浏览器不一致性和可伸缩性不足)。
  • 渐进增强,支持可能不支持高级 JavaScript 功能的用户代理。

我用通俗的语言来定义它。

“编写您的 JavaScript,使其不与 HTML 紧密耦合。JavaScript 可以访问 DOM 元素,JavaScript 可以操作 DOM 元素,但不能直接连接到它。”

在上面的例子中,jQuery Unobtrusive JavaScript 只是使用了一些 input 元素的属性并实现了客户端验证。

能否在不使用 HTML 辅助类的情况下使用这些 JavaScript 验证?

是的,为此我们必须手动将这些属性附加到元素上。

HTML 辅助函数和纯 HTML 哪个更受欢迎?

我个人更喜欢纯 HTML,因为 HTML 辅助函数再次剥夺了我们对 HTML 的“完全控制权”,而我们已经讨论过这个问题。

其次,让我们谈谈一个项目,其中使用了 jQuery 以外的其他 JavaScript 框架/库。像 Angular 这样的其他框架。在这种情况下,我们主要考虑 Angular 验证,在这种情况下,这些自定义 HTML 验证属性将付之东流。

结论

我们在这里完成了第 4 天的学习。在第 5 天,我们将学习更多高级内容,并带来更多乐趣。

FacebookLinkedInTwitter 上与我们联系,以随时了解新版本。

关于孟买的离线技术培训,请访问 StepByStepSchools.Net。在线培训请访问 JustCompile.comwww.Sukesh-Marla.com

如果您想从 MVC 5 开始,请从下面的视频“2 天学会 MVC 5”开始。

© . All rights reserved.