ASP.NET 5

ASP.NET 5 预览版简介

Daniel Roth

ASP.NET 最初是作为 Microsoft .NET Framework 1.0 的一部分提供,在 2002 年与 Visual Studio 一起发布。演变自 Active Server Pages (ASP) 的 ASP.NET 引入了面向对象的设计、.NET 基类库 (BCL),以及更好的性能等等。ASP.NET 旨在使习惯于编写桌面应用程序的开发人员能够轻松地使用 ASP.NET Web 窗体构建 Web 应用程序。随着 Web 的发展,ASP.NET 中不断有新框架加入:2008 年的 MVC、2010 年的 Web Pages、2012 年的 Web API 和 SignalR。所有这些新框架基于 ASP.NET 1.0 的基础构建。

因为有了 ASP.NET 5,ASP.NET 正经历着重塑,就像 2002 年将 ASP 重塑为 ASP.NET。重塑带来了许多新的特性:

  • 全面的并行支持:ASP.NET 5 应用程序现在可以安装在计算机上,而不会影响计算机上任何其他的应用程序。
  • 跨平台支持:ASP.NET 5 可运行在 Windows、Mac 和 Linux 上并受到支持。
  • 云就绪:诸如诊断、会话状态、缓存和配置等功能即可运行在本地也可运行在云中。
  • 更快的开发:删除了生成步骤;仅保存源文件并刷新浏览器,编译将自动进行。
  • MVC、Web Pages 和 Web API:所有这些合并在一起,简化了概念的数目。
  • 灵活的托管:现在您可以将自己整个的 ASP.NET 5 应用程序托管在 IIS 上或自己的进程中。

ASP.NET 5 预览版入门

在这篇文章中,我将概述 ASP.NET 开发团队(我也参与其中)为 ASP.NET 5 和 Visual Studio 2015 预览版创建的新体验。有关构建和运行 ASP.NET 5 应用程序的常规帮助,请访问 asp.net/vNext,您可以在其中查找到分步指南和其他文档。此外,我们还将定期发布更新至 blogs.msdn.com/b/webdev。开始之前,需下载并安装 Visual Studio 2015 预览版。

ASP.NET 5 运行时概述

ASP.NET 5 经过了彻底重建,以支持构建现代 Web 应用程序和服务。它是开源的、跨平台的,既可以在本地也可在云中工作。ASP.NET 5 的开发正在 GitHub 上进行的如火如荼,目前推出的为预览版 (github.com/aspnet)。我会简要介绍 ASP.NET 5 预览版中的新增功能,并提供可供深入了解的参考信息。

灵活的、跨平台运行时在其基础上,ASP.NET 5 以新的灵活运行时主机为根基。您可以针对三种不同的运行时灵活地选择其中之一运行应用程序:

  1. Microsoft .NET Framework:您可以在现有的 .NET Framework 上运行 ASP.NET 5 应用程序。这可以为您现有的二进制文件提供最大程度的兼容性。
  2. .NET Core:.NET Framework 的重构版本,可作为一组 NuGet 程序包随附在您的应用程序中。使用 .NET Core,您能得到真正的并行版本控制支持,并且可以在现有的基础结构中随意使用最新的 .NET 功能。请注意,.NET Core 上并没有提供所有的 API,现有的二进制文件通常需要重新编译才能在 .NET Core 上运行。
  3. Mono:Mono CLR 使您能够在 Mac 或 Linux 设备上开发并运行 ASP.NET 5 应用程序。有关详细信息,请参阅博客文章“在 Mac 上开发 ASP.NET vNext 应用程序”(bit.ly/1AdChNZ)。

无论使用哪一个 CLR,ASP.NET 5 都会利用一个公共基础结构来托管 CLR,并向此应用程序提供各种服务。该基础结构称为 K 运行时环境 (KRE)。虽然 KRE 中“K”的出处有些神秘(为了向 Katana 项目致敬?K 是指 Krazy Kool?),但 KRE 确实可为您提供托管并运行应用程序所需的一切。

新的 HTTP 管道 ASP.NET 5 引入了一种新的模块化 HTTP 请求管道,可以托管在您所选的服务器上。您可以将 ASP.NET 5 应用程序托管在 IIS 上、任何基于 Open Web Interface for .NET (OWIN) 的服务器上或您自己的进程中。因为您为自己的应用程序明确挑选了运行在管道中的中间件,所以您可以根据需要运行或多或少的功能,并充分利用裸机功能。ASP.NET 5 包括用于安全性、请求路由、诊断的中间件以及自己设计的自定义中间件。例如,这里有一个简单的中间件实现,可用来处理 X-HTTP-Method-Override 头:

app.Use((context, next) =>
{
  var value = context.Request.Headers["X-HTTP-Method-Override"];
  if (!string.IsNullOrEmpty(value))
  {
    context.Request.Method = value;
  }
  return next();
});

ASP.NET 5 使用的 HTTP 管道模型在许多方面类似随 Katana 项目引入的基于 OWIN 的模型,但有几处明显改进。与 Katana 类似,ASP.NET 5 支持 OWIN,但其通过将易于使用的轻量型 HttpContext 抽象包含在内而简化了开发。

有一个可用于此的程序包程序包管理器改变了开发人员对安装、更新以及管理依赖关系的思考方式。在 ASP.NET 5 中,所有的依赖关系都由程序包体现。NuGet 程序包是参考单位。ASP.NET 5 简化了从程序包源构建、安装和使用程序包,还可以与节点程序包管理器 (NPM) 以及 Bower 上的社区程序包结合使用。ASP.NET 5 引入了一个简单的 JSON 格式 (project.json) 以管理 NuGet 程序包依赖关系并提供跨平台构建基础结构。project.json 文件示例如图 1 所示(有关对各个受支持属性的详细解释,可访问 GitHub bit.ly/1AIOhK3)。

图 1 project.json 文件示例

{
  "webroot": "wwwroot",
  "version": "1.0.0-*",
  "exclude": [
    "wwwroot"
  ],
  "packExclude": [
    "**.kproj",
    "**.user",
    "**.vspscc"
  ],
  "dependencies": {
    "Microsoft.AspNet.Server.IIS": "1.0.0-beta1",
    "Microsoft.AspNet.Diagnostics": "1.0.0-beta1"
  },
  "frameworks" : {
    "aspnet50" : { },
    "aspnetcore50" : { }
  }
}

最佳的 C# ASP.NET 5 应用程序的设计时和运行时编译是通过使用托管 .NET 编译器平台(以前的代号为“Roslyn”)进行处理的。这意味着您可以使用最新的 C# 语言功能并利用内存中编译,以避免不必要的磁盘 I/O。ASP.NET 5 项目基于一个新的项目系统,此系统可在您进行编码时动态实时地编译应用程序,从而可以避免出现特定构建步骤的中断。通过解释性语言的灵活和感受使您可以充分发挥 .NET 和 C# 的威力。

内置依赖关系注入所有 ASP.NET 5 应用程序都可以访问一个公共依赖关系注入 (DI) 服务,从而帮助简化合成和测试。所有基于 ASP.NET 5 建立的 ASP.NET 框架(MVC、Web API、SignalR 和 Identity)都可以利用这一公共 DI 服务。如果 ASP.NET 5 随附了用于启动系统的极简控制反转 (IoC) 容器,那么您可以轻松使用您选择的容器替换该内置 IoC 容器。

熟悉的 Web 框架 ASP.NET 5 包括各种框架,可用于构建 Web 应用程序和服务,如 MVC、Web API、Web Pages(在将来版本中提供)、SignalR 和 Identity。这些框架都已进行移植以基于新的 HTTP 请求管道工作,并对其进行构建以支持在 .NET Framework、.NET Core 上或跨平台运行。

现在,现有的 MVC、Web API 和 Web Pages 实现可共享许多概念和重复的抽象,但是在实际实现中却共享甚少。作为将这些框架移植到 ASP.NET 5 的一部分,Microsoft 决定以一种新的眼光看待将这些框架组合为一个统一的 Web 堆栈。ASP.NET MVC 6 集 MVC、Web API 和 Web Pages 之所长,并将其组合至单一框架中以构建 Web UI 和 Web API。这意味着从单一的控制器,您就可以像呈现视图那样轻松地基于内容协商返回格式化数据。

除了统一,ASP.NET MVC 6 还引入了许多新功能:

  • 内置 DI 支持
  • 能够从任何类创建控制器,无需基类
  • 基于操作的请求分派
  • 视图组件,针对子操作的简单替换
  • 路由改进,包括简化的属性路由
  • 带有刷新点的异步视图
  • 能够使用 @inject 将服务器和帮助程序注入视图
  • ViewStart 继承
  • 标记帮助程序

您可以访问 github.com/aspnet/mvc 以获取更多信息和示例。

Web 窗体在 ASP.NET 5 上不可用,但在 .NET Framework 上仍完全受支持。即将推出的 .NET Framework 版本针对 Web 窗体推出了许多重要的新功能,包括支持 HTTP 2.0、异步模型绑定和基于 Roslyn 的 CodeDom 提供程序。我们还努力在 MVC6 中实现各种可以让人想起 Web 窗体的功能,如标记帮助程序和其他 Razor 改进。

实体框架

数据是许多应用程序的关键组成部分,ASP.NET 开发人员普遍选择实体框架 (EF) 访问数据。虽然 EF7 并不特定于 ASP.NET,但这个新版本的 EF 在 ASP.NET 5 中却扮演着不可或缺的角色。

EF7 支持新平台 EF 广泛应用于针对完整 .NET Framework 的客户端和服务器应用程序。EF7 的重点在于支持在 .NET 开发很常见的剩余平台上使用 EF。其中包括 ASP.NET 5、Windows 应用商店和 Windows Phone 应用程序,以及基于 .NET 的 Mac 和 Linux 应用程序。

对于 Windows Phone 和 Windows 应用商店应用程序,最初的目标是支持使用 EF 访问本地数据。SQLite 是设备上选择的最常用数据库,同时也将通过 EF7 成为设备上本地数据的主要存储。不过,因为即将推出完整的提供程序模型,所以其他数据存储也可获得支持。

EF7 支持新的数据存储尽管部分 EF 明确地依赖于关系数据存储,但 EF 提供的大部分功能也适用于许多非关系数据存储。这样的功能示例包括更改跟踪、LINQ 和工作单元。EF7 将支持针对非关系数据存储的提供程序,如 Microsoft Azure 表存储。

我们不会试图构建隐藏您正锁定的数据存储类型的抽象层,这一点很明确。适用于大多数数据存储的常用模式/组件将由核心框架处理。特定数据存储类型的具体事项将作为提供程序特定的扩展进行提供。例如,允许您配置自己的模型的模型生成器的概念将成为核心框架的一部分。然而,配置能力(如配置外键约束上的级联删除)将作为扩展包含在关系数据库提供程序中。

EF7 轻型且可扩展 EF7 是一个以提供某些常用功能为主的轻型可扩展版本。此外,我们将在其中包括一些在 EF6 代码库中很难实现的常见请求功能,EF7 一开始就会具备这些功能。

团队会保留您在 EF 中已经习惯的模式和概念,并只对确实需要更改的地方做出改动。您会看到同样的基于 DbContext/DbSet 的 API,只是它的构建基于根据需要易于替换或扩展的构造块组件 — 这一模式还用于添加至最近 EF 版本中的一些单独组件。

有关 EF7 的详细信息有关 EF7 的详细信息,请访问“EF7 究竟是什么”GitHub 页面 aka.ms/AboutEF7。该页面包含设计信息、到博客的链接以及试用 EF7 的说明。

ASP.NET 命令行工具

在我们构建工具体验之前提供命令行体验是核心 ASP.NET 5 宗旨之一。这意味着您几乎所有需要使用 ASP.NET 5 应用程序执行的任务都可以通过命令行进行。这么做的主要原因是,确保让那些使用 Mac 或 Linux 设备的开发人员在没有 Visual Studio 的情况下使用 ASP.NET 5 时可以有个可行选择。

KVM 要获得 ASP.NET 5 的完整命令行体验,您需要的第一个工具是 K 版本管理器 (KVM)。KVM 命令行工具可以下载新版本的 KRE,并允许您在二者之间进行切换。KRE 包含了其他您可能会使用的命令行工具。KVM 的实现方式、获取方法均取决于 OS。您可以从 github.com/aspnet/Home 运行适当的命令以下载并安装适合您的平台的 KVM。

安装了 KVM 之后,您应该能够打开一个命令提示符并运行 kvm 命令。运行“kvm list”将列出计算机上所有的 KRE 版本,如图 2 所示。

在命令行运行“kvm list”以获取计算机上的 KRE 版本列表
图 2 在命令行运行“kvm list”以获取计算机上的 KRE 版本列表

如果列表中没有条目,则表示您的用户配置文件中没有任何 KRE 版本。为了解决这个问题,您可以运行命令“kvm upgrade”。此命令将可确定可用的最新 KRE 版本,下载该版本并修改 PATH 环境变量,以便您可以使用 KRE 自身内的其他命令行工具。

您可以使用“kvm install <version/latest>”安装一个特定版本,而无需将之设为默认版本。使用 -r 开关指示是需要 KRE 的 .NET Core 版本还是 .NET Framework 版本,使用 -x86 和 -amd64 开关指示是下载 32 位还是 64 位的 KRE。运行时和位数开关可提供用来安装或升级。

调用了“kvm upgrade”之后,就可以使用 K 或 KPM 命令。K 可用于运行应用程序,而 KPM 用于管理程序包。

KVM 的工作原理?实质上,KVM 仅仅是一个操作 PATH 的便利方式。当您使用“KVM use <version>”时,其所做的就是将您的 PATH 更改到您在 PATH 上指定的 KRE 版本的 bin 文件夹。默认情况下,通过将 KRE.zip 文件复制并提取到 %USERPROFILE%\.kre\packages 来安装 KRE,因此,当您键入“KVM use 1.0.0-beta1”时,KVM 将确保 %USERPROFILE%\.kre\packages\KRE-CLR-x86.1.0.0-beta1\bin 位于您的 PATH 上。

KPM 您将要使用的下一个工具是 KRE 程序包管理器 (KPM)。KPM 执行两个主要功能,以及一些次要功能:

  1. 您可以在含有 project.json 文件的文件夹中运行“kpm restore”以下载应用程序所需的所有程序包。
  2. 其提供 pack 命令“kpm pack”,该命令将获取您的应用程序,并为您的应用程序生成一个可运行的独立映像。这里,映像表示专门用于复制到服务器并运行的文件夹结构。其中包括您的应用程序所需的所有程序包,以及您要在其上运行应用程序的 KRE(可选)。

restore 命令可以运行在包含 project.json 文件的文件夹中。其会检查该文件,使用 NuGet.config 连接到 NuGet 源,并尝试下载应用程序所需的所有程序包。默认情况下,其会将这些程序包安装在 %USERPROFILE%\.kpm\packages 中,以便任何给定程序包的副本只有一个需要置于您的开发计算机上,即使已用于多个项目中。

通过运行“kpm pack”打包您的应用程序将生成一个文件夹,其中包含应用程序运行所需的全部内容,包括程序包、源文件和您的 Web 根目录。您甚至可以选择包括 KRE,但默认情况下假设 KRE 已在服务器上。

K 命令 K 命令实际上是从命令行运行 ASP.NET 5 应用程序。与 KPM 一样,K 命令也包含在 KRE 中,是在 KRE 之上运行应用程序的入口点。

使用 K 命令的主要方式是在 project.json 文件内运行命令之一。这些命令由命令属性下 project.json 文件中的名称指定。默认情况下,ASP.NET 5 Starter Web 模板在 project.json 中包含一个托管您的应用程序并侦听端口 5000 的“web”命令。要运行此命令,只需运行“k web”。

针对 ASP.NET 5 的 Visual Studio 更新

ASP.NET5 的最初目标之一是为成员使用各种不同工具的团队提供出色体验。例如,您可以让使用 Windows 和 Visual Studio 的团队成员与在 Mac 上使用 Sublime Text 的其他成员协同工作(请参阅为跨平台 .NET 开发工具提供的选项 omnisharp.net)。为了实现这一目标,我们必须退后一步,重新思考 Visual Studio 支持。在 Visual Studio 的早期版本中,项目系统假定大多数开发都是在 Visual Studio 中进行的。当其他工具也参与创建文件或修改项目时,Visual Studio 就无法正常工作。例如,在 .csproj 文件中,Visual Studio 保留着构成项目的文件列表。如果您使用某种工具为项目创建了一个新文件,那么接下来您必须编辑 .csproj 文件,才能将该文件包含在内。

在 Visual Studio 2015 中,当您创建一个新的 ASP.NET 5 项目后,就会获得一种全新的体验。您仍然可以像往常一样开发、调试和运行项目,但除了 ASP.NET 项目中您已熟知的标准功能外,ASP.NET 5 中还增加了一些独有的新功能。您现在可以自由选择使用平台和工具进行开发了。我将对其中的一些功能进行探讨。

支持文件夹中的所有文件在 ASP.NET 5 中,项目目录下的所有文件都将自动包含在项目中。您可以在 project.json 文件中免除对文件的编译或发布。有关如何在 project.json 中排除文件的详细信息,请参阅 GitHub 页面:bit.ly/1AIOhK3。加载项目后,Visual Studio 将启动文件观察程序并更新解决方案资源管理器以反映更改。因为解决方案资源管理器始终观察项目目录下的文件,所以我们更改了生成文件进行存储的位置。除了将生成文件存储在项目下 (bin\ and obj\),我们现在还可将生成文件默认存放在解决方案文件旁名为 artifacts 的文件夹中。

只需编辑、保存和刷新浏览器在现有的 ASP.NET 应用程序中,更改服务器端逻辑(如您的 MVC 控制器代码,或过滤器)后,您需要重新生成并重新部署应用程序以查看反映在浏览器中的变化。Microsoft 希望 Web 开发人员工作流能够如同使用解释平台(如 Node.js 或 Ruby)那样轻巧便捷,同时还可充分利用 .NET 功能。在 ASP.NET 5 项目中,编辑和保存 C# 代码时,文件观察程序就会检测更改并重新启动应用程序。应用程序在内存中重新生成,因此,您可以近乎实时地在浏览器中看到变化结果。请注意,只有在不进行调试时才会支持此工作流,以免调试会话被打断。

NuGet 程序包的更新支持在 ASP.NET 5 中,所有依赖关系都是 NuGet 程序包。程序包依赖关系列在 project.json 中,并且只列出直接引用。运行时为您解决程序包依赖关系,您可以在解决方案资源管理器中通过整个程序包依赖关系图表进行查看和搜索。

要安装 NuGet 程序包,只需将程序包添加到 project.json 文件即可。只要保存 project.json 文件,就会启动程序包还原命令,对依赖关系所做的任何更改都会反映在解决方案资源管理器中的“引用”节点中。您可以在“输出”窗口中查看程序包还原结果以及任何可能出现在程序包管理器日志中的错误。对于通过 Visual Studio 本地安装在计算机上的程序包和公共 NuGet 源上提供的程序包,您甚至可以使用 IntelliSense,如图 3 所示。

针对 project.json 中的 NuGet 程序包依赖关系使用 IntelliSense
图 3 针对 project.json 中的 NuGet 程序包依赖关系使用 IntelliSense

在现有的 ASP.NET 项目中,在将 NuGet 程序包安装到某个项目中后,该 NuGet 程序包的副本(及其所有依赖关系)将被放置在解决方案附近的程序包文件夹中。在 ASP.NET 5 中,使用缓存可便于每位用户跨项目共享 NuGet 程序包。当 ASP.NET 5 中出现程序包还原时,任何已安装在缓存中的程序包只是简单地进行重复使用。您可以查看和修改 .kpm 文件夹下用户配置文件中的程序包缓存。

默认情况下,ASP.NET 5 项目由运行时在内存中生成,并且没有任何项目保存在磁盘上。但是,可以轻松地为 ASP.NET 5 类库生成 NuGet 程序包,方法是,在项目的属性页的“生成”选项卡上选中“Produce all outputs on build”复选框。选择此选项后,您可以在解决方案的 artifacts 文件夹下找到生成的 NuGet 程序包。

生成并获取多个目标框架的组合 IntelliSense 在 ASP.NET 5 中,您将目标框架列在 project.json 中。您的项目对照所列的每个目标框架进行生成。这可以更快地发现问题,因为您不必显式切换到目标框架,还可以在单个项目中针对多个目标框架进行交叉编译。

我们还通过组合 IntelliSense 更新了 ASP.NET 5 项目的 IntelliSense 体验。使用组合 Intellisense 之后,当一个或多个目标框架的给定完成的 IntelliSense 存在差异,您会看到显示这些差异的扩展工具提示。图 4 中的 StringComparison 类就是很好的示例。

针对多个目标框架显示组合 IntelliSense 的工具提示
图 4 针对多个目标框架显示组合 IntelliSense 的工具提示

图 4 中,您可以看到,使用 ASP.NET Core 5.0 时,InvariantCulture 值不适用于 StringComparison 枚举。

Web 发布在 Visual Studio 2015 中,Microsoft 开发人员正在致力于 ASP.NET 5 项目的新发布进程。在预览版中,ASP.NET 5 发布支持发布到 Azure 网站和文件系统(例如,本地/网络文件夹)。当发布到 Azure 网站时,您可以选择所需的生成配置和 KRE 版本。以后的版本会将其扩展为支持更广泛的目标。

迁移至 ASP.NET 5

将现有的 Web 应用程序移至 ASP.NET 5 会涉及到为现有的应用程序创建新的 ASP.NET 5 项目,然后将代码和依赖关系迁移至新的框架上运行。为应用程序创建新的 ASP.NET 5 项目相对比较简单。首先,在项目文件夹中添加一个 project.json 文件。最初,project.json 文件只需要包括一个空的 JSON 对象(例如,{})。接下来,使用“文件”|“打开项目”,在 Visual Studio 2015 预览版中打开 project.json 文件。打开 project.json 文件后,Visual Studio 将创建一个含有 .kproj 文件的 ASP.NET 5 项目,并自动将在 project.json 文件附近找到的所有文件和目录都包含在该项目中。您应该能够在解决方案资源管理器的新 ASP.NET 5 项目中看到您的项目文件。您现在已经为现有的 Web 应用程序创建了一个 ASP.NET 5 项目!

迁移您的代码和依赖关系以便新的 ASP.NET 5 项目可以正确生成和运行,这是一个比较复杂的过程。您需要更新您的 project.json,其中涉及您的顶层程序包的依赖关系、框架程序集引用和项目引用。您需要迁移您的代码以使用新的 HTTP 抽象、新的中间件模型和新版本的 ASP.NET Web 框架。您需要移至新的基础结构以处理诸如配置、日志记录和 DI 之类的问题。移植您的应用程序以在 .NET Core 上运行,这需要应对额外的平台变化和限制。这已经超出了本文所涉及的范畴,但我们正努力在以后的文章中提供完整的迁移指南。虽然转移到 ASP.NET 5 可能耗资巨大,但 Microsoft 认为提供一个开源的、由社区驱动的、跨平台和云就绪的框架能够带来的好处值得付出额外的努力。

下一步该怎么做?

在本文中,我从高级概念到低级组件对 ASP.NET 5 进行了探讨。要学习的东西太多了!幸运的是,有大量的资源可以提供帮助。

ASP.NET 网站为此专门开辟了一个内容区域(asp.net/vnext)。此页面会就功能发布消息、文档、教程和社区资源不断进行更新。

ASP.NET vNext 社区站立会议是有 ASP.NET 团队参与的开放性周会。该会议的举办时间是每周二,在太平洋时间的上午和下午之间交替进行,所以世界各地的开发人员都可以参加。快来加入我们,听听接下来会推出什么,还可以提出问题,并给出您的反馈意见。

您可以在专门的 ASP.NET vNext 论坛 (bit.ly/1xOuQx9) 得到同行开发人员和 ASP.NET 团队成员的帮助。在 JabbR.net 上还有一个专注于 ASP.NET 5/vNext 开发的聊天室:bit.ly/1HDAGFX

ASP.NET 5 是作为开源项目在进行开发,因此您可以参与到开发过程中。github.com/aspnet 下的源代码存储库是团队开发时会用到的真正的实时存储库,而不是内部存储库的镜像。这意味着您可以看到正在发生的提交,并随时可以抓取代码的快照。该存储库包括框架的源代码(例如,KRuntime、Razor 和 MVC),以及功能测试和示例项目。我们鼓励您通过在 GitHub 存储库公开或点评问题留下反馈(包括 Bug 和功能建议)。

这对于在 Microsoft Web 平台上进行 Web 开发来说是一个激动人心的时刻!我们鼓励您尽早参与进来,这样您可以抢先试用新功能,从而在开发过程中提供反馈。

最后,我要感谢 Glenn Condron、Jon Galloway、Sayed Ibrahim Hashimi、Scott Hunter 和 Rowan Miller 应邀为本文做出了超越常规技术审阅的工作,实质上他们对于本文重要部分的编撰功不可没。


Daniel Roth 是目前正专注于 ASP.NET 5 的 ASP.NET 团队的资深项目经理。他热衷于 .NET 开发,致力于让框架变得简单易用以使客户更加满意。

衷心感谢以下 Microsoft 技术专家对本文的审阅:Glenn Condron、David Fowler、Jon Galloway、Sayed Ibrahim Hashimi、Scott Hunter、Rowan Miller 和 Praburaj Thiagaraj