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

ASP.NET MVC 模型绑定入门 - 绝对初学者教程

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.84/5 (59投票s)

2014 年 1 月 15 日

CPOL

5分钟阅读

viewsIcon

269139

downloadIcon

2712

在本文中,我们试图理解什么是 ASP.NET MVC 模型绑定

引言

在本文中,我们试图理解什么是 ASP.NET MVC 模型绑定。我们将通过一些代码示例来理解模型绑定,以及为什么它对于 ASP.NET MVC 应用程序开发非常有用和必不可少。

背景

每当我与那些刚开始使用 ASP.NET MVC 的有经验的 ASP.NET Web Forms 开发人员交谈时,我经常会听到一个问题:“当 HTML 表单(视图)中的值到达控制器类的 Action 方法时,它们是如何转换为 Model 类的?”。

这个问题的答案是,所有这些魔法都是由 ASP.NET 模型绑定器完成的。模型绑定器所做的是,它会获取来自 HTML 页面的值,并将其映射到相应的模型。这非常有益,因为它让开发人员不必编写所有“类型转换”和“HTML-模型映射”的代码。模型绑定器能够从 HTML 表单变量、POST 变量和文件、查询字符串参数以及路由中添加的值中检索数据。

这似乎是一项非常简单的任务,我们可以自己完成,而无需模型绑定器,但实际上,如果手动进行此映射,可能会非常耗时、繁琐且容易出错。在本文中,我们将尝试在不利用模型绑定的情况下实现一个简单的解决方案,然后我们将尝试看看模型绑定如何使我们免于编写大量单调的代码。

使用代码 

让我们先看看一个例子,其中我们将从 Request 中提取所有值,然后手动填充我们的模型。所以,我们首先需要创建一个模型。让我们为 `Student` 创建一个简单的模型类。

public class Student
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public DateTime DOB { get; set; }        
    public string FathersName { get; set; }
    public string MothersName { get; set; }
}

现在,让我们创建一个简单的视图,其中包含一个用于填充 `Student` 详细信息的表单。

 

现在,让我们在 `StudentController` 中创建简单的 Action 方法,看看如何在控制器中获取这些值。

public ActionResult Create()
{
    return View();
}

[HttpPost]
public ActionResult Create(FormCollection collection)
{
    try
    {
        // TODO: Add insert logic here

        return RedirectToAction("Index");
    }
    catch
    {
        return View();
    }
}     

现在,让我们在 HTML 表单中填写一些数据并调试我们的 Action 方法。

 

我们可以看到,从表单中 POST 的值在 `FormCollection` 以及 `Request.Form` 中可用。我们可以使用其中任何一个值来填充我们的 `Student` 模型。让我们继续编写一些代码来从 POST 的数据中创建 `Student` 模型。我们使用 `FormCollection` 来实现这一点,但也可以使用 `Request.Form`。

[HttpPost]
public ActionResult Create(FormCollection collection)
{
    try
    {   
        Student student = new Student();

        student.FirstName = collection["FirstName"];
        student.LastName = collection["LastName"];
        DateTime suppliedDate;
        DateTime.TryParse(collection["DOB"], out suppliedDate);
        student.DOB = suppliedDate;
        student.FathersName = collection["FathersName"];
        student.MothersName = collection["MothersName"];

        studentsList.Add(student);
        return RedirectToAction("Index");
    }
    catch
    {
        return View();
    }
}        

在上面的代码片段中,我们正在从 HTML 表单的 POST 值中提取所有数据,然后将值映射到 `Student` 属性并进行赋值。我们还在需要进行类型转换的地方进行了类型转换,因为提供的值的格式与模型属性的格式不符。这看起来并不算太糟。那么,我们为什么还需要模型绑定器呢?

考虑以下场景

  1. 我们的模型包含很多属性,我们需要手动映射所有这些属性。
  2. 我们的模型包含很多属性,其中大部分需要进行类型转换才能赋值给模型属性。
  3. 我们的视图是强类型的视图模型。我们需要弄清楚哪个值应该赋给哪个模型(视图模型中的模型)并手动赋值。
  4. 我们的模型包含其他模型对象,而这些包含的模型对象又可以包含其他模型对象。
  5. 模型是一个自引用模型,即模型包含其自身类型的对象。

上面提到的场景并非如你所想的那么假设。这些是大多数开发人员会遇到的场景。现在,想象一下在所有这些场景中,都需要我们手动执行模型绑定。这正是我们可以利用 ASP.NET MVC 模型绑定的强大功能和易用性的地方。

ASP.NET MVC 模型绑定所有来自 HTTP 世界的数据,并使用 `DefaultModelBinder` 类,该类神奇地完成了所有类型转换以及将所有这些值映射到模型属性的工作。如果我们使用模型绑定器,那么我们就无需编写转换和映射代码,这将使我们的控制器类更加简洁。届时,我们的控制器只需要关注需要对这个接收到的模型做什么,而不是如何创建这个模型。

让我们继续使用模型绑定器来执行我们之前进行的操作。要使用模型绑定器,我们需要做什么?我们只需要更改 `Create` 方法的参数,使其接受 `Student` 模型对象而不是 `FormCollection`。

[HttpPost]
public ActionResult Create(Student student)
{
    try
    {
        if (ModelState.IsValid)
        {
            studentsList.Add(student);
            return RedirectToAction("Index");
        }
    }
    catch
    {
        return View("Create");
    }

    return View("Create");
}    

现在,模型绑定的魔法取决于提供值的 HTML 变量的 ID。对于我们的学生模型,HTML 输入字段的 ID 应该与 Student 模型的属性名称相同。默认情况下,映射将基于属性名称。这正是 HTML 辅助方法将非常有用的地方,因为这些辅助方法将生成具有正确 `Names` 的 HTML,以便模型绑定能够正常工作。

所以,要创建 Student FirstName 属性的 HTML 输入字段

 @Html.EditorFor(model => model.FirstName)

这将确保生成的 HTML 具有正确的 `Name`,以便模型绑定器在检索值时能够理解它。

 

因此,我们可以看到使用模型绑定和 HTML 辅助方法如何使我们免于编写大量的单调的类型转换和模型映射代码。如果默认模型绑定器不适合我们,我们也可以实现自己的自定义模型绑定器。此外,还有一点需要注意,如果我们需要从除默认提供者之外的其他提供者获取值,例如我们需要从 `LocalStorage` 获取某些值,那么我们也可以实现自定义值提供者。

值得关注的点:

在本文中,我们只讨论了什么是 ASP.NET 模型绑定,并对模型绑定器进行了基本介绍。可以通过实现自定义模型绑定器和值提供者来定制模型绑定过程。但由于本文是为 ASP.NET MVC 绝对初学者准备的,因此此处未详细介绍这些主题。我希望本文有所启发。

历史

  • 2014年1月15日:初始版本
© . All rights reserved.