检查自动生成的详细信息和删除方法

作者 :Rick Anderson

注意

此处使用最新版本的 Visual Studio 提供了本教程的更新版本。 新教程使用 ASP.NET Core MVC,这比本教程提供了许多改进。

本教程介绍具有控制器和视图的 ASP.NET Core MVC。 Razor Pages 是 ASP.NET Core 中的一种新替代方法,它是一种基于页面的编程模型,可简化 Web UI 的生成过程并提高效率。 建议先尝试 Razor 页面教程,再使用 MVC 版本。 Razor 页面教程:

  • 易于关注。
  • 涵盖更多功能。
  • 是新应用开发的首选方法。

在本教程的这一部分,你将检查自动生成 Details 的 和 Delete 方法。

检查 Details 和 Delete 方法

打开 Movie 控制器并检查 Details 方法。

显示“电影控制器”点 c s 选项卡的屏幕截图。在“创建”下拉菜单中,“详细信息”以红色圈出。

public ActionResult Details(int? id)
{
    if (id == null)
    {
        return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
    }
    Movie movie = db.Movies.Find(id);
    if (movie == null)
    {
        return HttpNotFound();
    }
    return View(movie);
}

创建此操作方法的 MVC 基架引擎会添加一条注释,其中显示了调用该方法的 HTTP 请求。 在本例中,它是一个包含三个 GET URL 段的请求, Movies 即控制器、 Details 方法和值 ID

Code First 使使用 Find 方法可以轻松搜索数据。 方法中内置的一个重要安全功能是,在代码尝试对它执行任何操作之前,代码会验证 Find 该方法是否已找到电影。 例如,一个黑客可能通过将链接创建的 URL 从 http://localhost:xxxx/Movies/Details/1 更改为类似 http://localhost:xxxx/Movies/Details/12345 的值(或者不代表任何实际电影的其他值)将错误引入站点。 如果未检查空电影,则 null 电影将导致数据库错误。

检查 DeleteDeleteConfirmed 方法。

// GET: /Movies/Delete/5
public ActionResult Delete(int? id)
{
    if (id == null)
    {
        return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
    }
    Movie movie = db.Movies.Find(id);
    if (movie == null)
    {
        return HttpNotFound();
    }
    return View(movie);
}

// POST: /Movies/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public ActionResult DeleteConfirmed(int id)
{
    Movie movie = db.Movies.Find(id);
    db.Movies.Remove(movie);
    db.SaveChanges();
    return RedirectToAction("Index");
}

请注意,HTTP GET Delete 方法不会删除指定的电影,它会返回电影的视图,你可以在其中提交 (HttpPost) 删除。 执行删除操作以响应 GET 请求(或者说,执行编辑操作、创建操作或更改数据的任何其他操作)会打开安全漏洞。 有关此内容的详细信息,请参阅 Stephen Walther 的博客文章 ASP.NET MVC 提示 #46 - 请勿使用删除链接,因为它们会创建安全漏洞

删除数据的 HttpPost 方法命名为 DeleteConfirmed,以便为 HTTP POST 方法提供一个唯一的签名或名称。 下面显示了两个方法签名:

// GET: /Movies/Delete/5
public ActionResult Delete(int? id)

//
// POST: /Movies/Delete/5
[HttpPost, ActionName("Delete")]
public ActionResult DeleteConfirmed(int id)

公共语言运行时 (CLR) 需要重载方法拥有唯一的参数签名(相同的方法名称但不同的参数列表)。 但是,在这里,需要两个 Delete 方法(一个用于 GET,一个用于 POST),这两种方法具有相同的参数签名。 (它们都需要接受单个整数作为参数。)

若要解决此问题,可以执行一些操作。 一种是为方法指定不同的名称。 这正是前面的示例中的基架机制进行的操作。 但是,这会造成一个小问题:ASP.NET 按名称将 URL 段映射到操作方法,如果重命名方法,则路由通常无法找到该方法。 该示例中也提供了解决方案,即向 DeleteConfirmed 方法添加 ActionName("Delete") 属性。 这会有效地为路由系统执行映射,以便包含 /Delete/ 的 POST 请求的 URL 将找到 DeleteConfirmed 方法。

避免具有相同名称和签名的方法出现问题的另一种常见方法是人为地更改 POST 方法的签名,以包含未使用的参数。 例如,某些开发人员添加传递给 POST 方法的参数类型 FormCollection ,然后根本不使用 参数:

public ActionResult Delete(FormCollection fcNotUsed, int id = 0)
{
    Movie movie = db.Movies.Find(id);
    if (movie == null)
    {
        return HttpNotFound();
    }
    db.Movies.Remove(movie);
    db.SaveChanges();
    return RedirectToAction("Index");
}

总结

现在,你已拥有一个完整的 ASP.NET MVC 应用程序,用于将数据存储在本地 DB 数据库中。 可以创建、读取、更新、删除和搜索电影。

显示“M V C 电影搜索索引”页的屏幕截图。

后续步骤

生成并测试 Web 应用程序后,下一步是使其可供其他人通过 Internet 使用。 为此,必须将其部署到 Web 托管提供程序。 Microsoft 在 免费的 Azure 试用帐户中为最多 10 个网站提供免费 Web 托管。 我建议你接下来按照我的教程将具有成员身份、OAuth 和SQL 数据库的安全 ASP.NET MVC 应用部署到 Azure。 一个优秀的教程是 Tom Dykstra 的中间级别 为 ASP.NET MVC 应用程序创建实体框架数据模型StackoverflowASP.NET MVC 论坛 是提问的绝佳场所。 在推特上关注 ,以便你可以获取我的最新教程的更新。

欢迎提供反馈。

里克·安德森 推特: @RickAndMSFT
斯科特·汉塞尔曼 推特: @shanselman